From 43098043c4ef31d9d5dead66568d7d9482a6b165 Mon Sep 17 00:00:00 2001 From: liamfallon Date: Tue, 25 Jan 2022 19:55:43 +0000 Subject: Rename TOSCA Control Loop to ACM This commit renames the TOSCA Control Loop functionality in CLAMP to Automation Composition Management. This review is a direct renaming review and, as everything is renamed together it is large. Issue-ID: POLICY-3939 Change-Id: I28f0a6dd889bf3570a4c1365ae9e71fc58db6d6c Signed-off-by: liamfallon --- .../participant-impl/participant-impl-cds/pom.xml | 2 +- .../clamp/acm/participant/http/Application.java | 49 +++ .../participant/http/config/ParticipantConfig.java | 43 ++ .../participant/http/config/SecurityConfig.java | 45 ++ .../main/exception/HttpWebClientException.java | 33 ++ .../AutomationCompositionElementHandler.java | 180 ++++++++ .../http/main/models/ConfigRequest.java | 51 +++ .../http/main/models/ConfigurationEntity.java | 40 ++ .../participant/http/main/models/RestParams.java | 54 +++ .../http/main/webclient/AcHttpClient.java | 135 ++++++ .../http/parameters/ParticipantHttpParameters.java | 46 ++ .../controlloop/participant/http/Application.java | 45 -- .../participant/http/config/ParticipantConfig.java | 43 -- .../participant/http/config/SecurityConfig.java | 45 -- .../main/exception/HttpWebClientException.java | 33 -- .../main/handler/ControlLoopElementHandler.java | 178 -------- .../http/main/models/ConfigRequest.java | 51 --- .../http/main/models/ConfigurationEntity.java | 40 -- .../participant/http/main/models/RestParams.java | 54 --- .../http/main/webclient/ClHttpClient.java | 135 ------ .../http/parameters/ParticipantHttpParameters.java | 47 -- .../src/main/resources/config/application.yaml | 10 +- .../http/handler/AcElementHandlerTest.java | 106 +++++ .../http/rest/ActuatorControllerTest.java | 92 ++++ .../http/utils/CommonActuatorController.java | 114 +++++ .../acm/participant/http/utils/CommonTestData.java | 137 ++++++ .../acm/participant/http/utils/ToscaUtils.java | 51 +++ .../http/webclient/AcHttpClientTest.java | 129 ++++++ .../http/handler/ClElementHandlerTest.java | 108 ----- .../http/rest/ActuatorControllerTest.java | 92 ---- .../http/utils/CommonActuatorController.java | 114 ----- .../participant/http/utils/CommonTestData.java | 152 ------- .../participant/http/utils/ToscaUtils.java | 51 --- .../http/webclient/ClHttpClientTest.java | 129 ------ .../src/test/resources/HttpParticipantConfig.yaml | 48 +-- .../src/test/resources/application_test.properties | 22 +- .../participant-impl-kubernetes/pom.xml | 2 +- .../acm/participant/kubernetes/Application.java | 49 +++ .../configurations/ParticipantConfig.java | 44 ++ .../ParticipantIntermediaryConfig.java | 43 ++ .../kubernetes/configurations/SecurityConfig.java | 45 ++ .../kubernetes/configurations/SpringFoxConfig.java | 45 ++ .../kubernetes/controller/ChartController.java | 195 +++++++++ .../kubernetes/exception/ServiceException.java | 32 ++ .../AutomationCompositionElementHandler.java | 197 +++++++++ .../participant/kubernetes/helm/HelmClient.java | 279 ++++++++++++ .../kubernetes/helm/PodStatusValidator.java | 119 ++++++ .../participant/kubernetes/models/ChartInfo.java | 44 ++ .../participant/kubernetes/models/ChartList.java | 31 ++ .../kubernetes/models/HelmRepository.java | 39 ++ .../kubernetes/models/InstallationInfo.java | 29 ++ .../parameters/ParticipantK8sParameters.java | 52 +++ .../kubernetes/service/ChartService.java | 141 ++++++ .../participant/kubernetes/service/ChartStore.java | 219 ++++++++++ .../participant/kubernetes/Application.java | 45 -- .../configurations/ParticipantConfig.java | 44 -- .../ParticipantIntermediaryConfig.java | 43 -- .../kubernetes/configurations/SecurityConfig.java | 45 -- .../kubernetes/configurations/SpringFoxConfig.java | 45 -- .../kubernetes/controller/ChartController.java | 195 --------- .../kubernetes/exception/ServiceException.java | 32 -- .../handler/ControlLoopElementHandler.java | 196 --------- .../participant/kubernetes/helm/HelmClient.java | 279 ------------ .../kubernetes/helm/PodStatusValidator.java | 119 ------ .../participant/kubernetes/models/ChartInfo.java | 44 -- .../participant/kubernetes/models/ChartList.java | 31 -- .../kubernetes/models/HelmRepository.java | 39 -- .../kubernetes/models/InstallationInfo.java | 29 -- .../parameters/ParticipantK8sParameters.java | 52 --- .../kubernetes/service/ChartService.java | 141 ------ .../participant/kubernetes/service/ChartStore.java | 219 ---------- .../src/main/resources/config/application.yaml | 16 +- .../AutomationCompositionElementHandlerTest.java | 182 ++++++++ .../kubernetes/helm/HelmClientTest.java | 158 +++++++ .../kubernetes/helm/PodStatusValidatorTest.java | 107 +++++ .../kubernetes/parameters/CommonTestData.java | 161 +++++++ .../parameters/ParticipantK8sParametersTest.java | 89 ++++ .../kubernetes/rest/ActuatorControllerTest.java | 92 ++++ .../kubernetes/rest/ChartControllerTest.java | 249 +++++++++++ .../kubernetes/service/ChartServiceTest.java | 148 +++++++ .../kubernetes/service/ChartStoreTest.java | 175 ++++++++ .../kubernetes/utils/CommonActuatorController.java | 114 +++++ .../participant/kubernetes/utils/TestUtils.java | 47 ++ .../handler/ControlLoopElementHandlerTest.java | 180 -------- .../kubernetes/helm/HelmClientTest.java | 158 ------- .../kubernetes/helm/PodStatusValidatorTest.java | 109 ----- .../kubernetes/parameters/CommonTestData.java | 161 ------- .../parameters/ParticipantK8sParametersTest.java | 89 ---- .../kubernetes/rest/ActuatorControllerTest.java | 92 ---- .../kubernetes/rest/ChartControllerTest.java | 249 ----------- .../kubernetes/service/ChartServiceTest.java | 148 ------- .../kubernetes/service/ChartStoreTest.java | 175 -------- .../kubernetes/utils/CommonActuatorController.java | 114 ----- .../participant/kubernetes/utils/TestUtils.java | 47 -- .../src/test/resources/application_test.properties | 22 +- .../resources/servicetemplates/KubernetesHelm.yaml | 58 +-- .../participant-impl-policy/pom.xml | 2 +- .../policy/PolicyParticipantApplication.java | 43 ++ .../policy/client/AbstractHttpClient.java | 76 ++++ .../policy/client/PolicyApiHttpClient.java | 87 ++++ .../policy/client/PolicyPapHttpClient.java | 85 ++++ .../policy/config/ParticipantConfig.java | 43 ++ .../participant/policy/config/SecurityConfig.java | 45 ++ .../AutomationCompositionElementHandler.java | 227 ++++++++++ .../parameters/ParticipantPolicyParameters.java | 62 +++ .../policy/PolicyParticipantApplication.java | 42 -- .../policy/client/AbstractHttpClient.java | 76 ---- .../policy/client/PolicyApiHttpClient.java | 87 ---- .../policy/client/PolicyPapHttpClient.java | 85 ---- .../policy/config/ParticipantConfig.java | 43 -- .../participant/policy/config/SecurityConfig.java | 45 -- .../main/handler/ControlLoopElementHandler.java | 220 ---------- .../parameters/ParticipantPolicyParameters.java | 62 --- .../src/main/resources/META-INF/persistence.xml | 10 +- .../src/main/resources/config/application.yaml | 10 +- .../policy/endtoend/ParticipantMessagesTest.java | 174 ++++++++ .../AutomationCompositionElementHandlerTest.java | 102 +++++ .../policy/main/parameters/CommonTestData.java | 181 ++++++++ .../ParticipantPolicyParametersTest.java | 67 +++ .../policy/main/rest/ActuatorControllerTest.java | 92 ++++ .../main/utils/CommonActuatorController.java | 114 +++++ .../policy/main/utils/TestListenerUtils.java | 321 ++++++++++++++ .../policy/endtoend/ParticipantMessagesTest.java | 174 -------- .../handler/ControlLoopElementHandlerTest.java | 102 ----- .../policy/main/parameters/CommonTestData.java | 180 -------- .../ParticipantPolicyParametersTest.java | 66 --- .../policy/main/rest/ActuatorControllerTest.java | 92 ---- .../main/utils/CommonActuatorController.java | 114 ----- .../policy/main/utils/TestListenerUtils.java | 317 -------------- .../src/test/resources/application_test.properties | 20 +- .../test/resources/parameters/TestACParams.yaml | 172 ++++++++ .../test/resources/parameters/TestCLParams.yaml | 172 -------- .../src/test/resources/parameters/logback-test.xml | 2 +- .../vCPE.policies.optimization.input.tosca.yaml | 348 --------------- .../resources/policytypes/onap.policies.Match.yaml | 8 - .../policytypes/onap.policies.Naming.yaml | 102 ----- .../policytypes/onap.policies.Optimization.yaml | 33 -- .../onap.policies.controlloop.guard.Common.yaml | 28 -- ...olicies.controlloop.guard.common.Blacklist.yaml | 16 - ...p.policies.controlloop.guard.common.Filter.yaml | 66 --- ....controlloop.guard.common.FrequencyLimiter.yaml | 26 -- ...p.policies.controlloop.guard.common.MinMax.yaml | 24 -- ...lloop.guard.coordination.FirstBlocksSecond.yaml | 27 -- ...ap.policies.controlloop.operational.Common.yaml | 143 ------- ...licies.controlloop.operational.common.Apex.yaml | 26 -- ...cies.controlloop.operational.common.Drools.yaml | 14 - .../onap.policies.monitoring.dcae-pm-mapper.yaml | 50 --- ...es.monitoring.dcae-pm-subscription-handler.yaml | 132 ------ ...policies.monitoring.dcae-restconfcollector.yaml | 128 ------ ...n2.collectors.datafile.datafile-app-server.yaml | 19 - .../onap.policies.monitoring.tcagen2.yaml | 161 ------- .../policytypes/onap.policies.native.Apex.yaml | 203 --------- .../policytypes/onap.policies.native.Drools.yaml | 118 ----- .../policytypes/onap.policies.native.Xacml.yaml | 20 - .../onap.policies.optimization.Resource.yaml | 25 -- .../onap.policies.optimization.Service.yaml | 17 - ...icies.optimization.resource.AffinityPolicy.yaml | 33 -- ...icies.optimization.resource.DistancePolicy.yaml | 58 --- ...p.policies.optimization.resource.HpaPolicy.yaml | 105 ----- ...s.optimization.resource.OptimizationPolicy.yaml | 68 --- ...p.policies.optimization.resource.PciPolicy.yaml | 32 -- ...nap.policies.optimization.resource.Vim_fit.yaml | 30 -- ...p.policies.optimization.resource.VnfPolicy.yaml | 46 -- ....policies.optimization.service.QueryPolicy.yaml | 26 -- ...cies.optimization.service.SubscriberPolicy.yaml | 36 -- .../pm_automation_composition_tosca.yaml | 164 +++++++ .../servicetemplates/pm_control_loop_tosca.yaml | 164 ------- .../participant-impl-simulator/pom.xml | 2 +- .../simulator/ParticipantSimulatorApplication.java | 46 ++ .../simulator/config/AafConfiguration.java | 46 ++ .../simulator/config/ParticipantConfig.java | 61 +++ .../simulator/config/SecurityConfig.java | 39 ++ .../simulator/config/SpringFoxConfig.java | 45 ++ .../simulator/config/YamlConfiguration.java | 43 ++ .../AutomationCompositionElementHandler.java | 112 +++++ .../parameters/ParticipantSimulatorParameters.java | 45 ++ .../main/rest/AbstractRestController.java | 130 ++++++ .../rest/GlobalControllerExceptionHandler.java | 45 ++ .../main/rest/ParticipantErrorController.java | 97 +++++ .../main/rest/ParticipantSimulatorAafFilter.java | 38 ++ .../simulator/simulation/SimulationProvider.java | 113 +++++ .../rest/SimulationElementController.java | 188 ++++++++ .../rest/SimulationParticipantController.java | 181 ++++++++ .../simulator/ParticipantSimulatorApplication.java | 46 -- .../simulator/config/AafConfiguration.java | 46 -- .../simulator/config/ParticipantConfig.java | 61 --- .../simulator/config/SecurityConfig.java | 39 -- .../simulator/config/SpringFoxConfig.java | 45 -- .../simulator/config/YamlConfiguration.java | 43 -- .../main/handler/ControlLoopElementHandler.java | 111 ----- .../parameters/ParticipantSimulatorParameters.java | 45 -- .../main/rest/AbstractRestController.java | 102 ----- .../rest/GlobalControllerExceptionHandler.java | 45 -- .../main/rest/ParticipantErrorController.java | 97 ----- .../main/rest/ParticipantSimulatorAafFilter.java | 38 -- .../simulator/simulation/SimulationProvider.java | 110 ----- .../rest/SimulationElementController.java | 183 -------- .../rest/SimulationParticipantController.java | 175 -------- .../src/main/resources/config/application.yaml | 6 +- .../src/main/resources/version.txt | 2 +- .../endtoend/ParticipantSimulatorTest.java | 288 +++++++++++++ .../AutomationCompositionElementHandlerTest.java | 91 ++++ .../simulator/main/parameters/CommonTestData.java | 140 ++++++ .../TestParticipantSimulatorParameters.java | 62 +++ .../simulator/main/rest/TestListenerUtils.java | 260 +++++++++++ .../endtoend/ParticipantSimulatorTest.java | 285 ------------ .../handler/ControlLoopElementHandlerTest.java | 98 ----- .../simulator/main/parameters/CommonTestData.java | 140 ------ .../TestParticipantSimulatorParameters.java | 62 --- .../simulator/main/rest/TestListenerUtils.java | 257 ----------- .../src/test/resources/application_test.properties | 14 +- .../pm_automation_composition_tosca.yaml | 164 +++++++ .../servicetemplates/pm_control_loop_tosca.yaml | 164 ------- participant/participant-intermediary/pom.xml | 4 +- .../api/AutomationCompositionElementListener.java | 65 +++ .../api/ParticipantIntermediaryApi.java | 130 ++++++ .../api/impl/ParticipantIntermediaryApiImpl.java | 140 ++++++ .../AutomationCompositionStateChangeListener.java | 48 +++ .../comm/AutomationCompositionUpdateListener.java | 48 +++ .../intermediary/comm/MessageSender.java | 78 ++++ .../intermediary/comm/ParticipantAckListener.java | 67 +++ .../comm/ParticipantDeregisterAckListener.java | 48 +++ .../intermediary/comm/ParticipantListener.java | 64 +++ .../comm/ParticipantMessagePublisher.java | 147 +++++++ .../comm/ParticipantRegisterAckListener.java | 48 +++ .../comm/ParticipantStatusReqListener.java | 47 ++ .../comm/ParticipantUpdateListener.java | 47 ++ .../handler/AutomationCompositionHandler.java | 476 +++++++++++++++++++++ .../handler/IntermediaryActivator.java | 153 +++++++ .../participant/intermediary/handler/Listener.java | 41 ++ .../intermediary/handler/ParticipantHandler.java | 416 ++++++++++++++++++ .../intermediary/handler/Publisher.java | 34 ++ .../ParticipantIntermediaryParameters.java | 61 +++ .../parameters/ParticipantParameters.java | 26 ++ .../api/ControlLoopElementListener.java | 63 --- .../api/ParticipantIntermediaryApi.java | 129 ------ .../api/impl/ParticipantIntermediaryApiImpl.java | 137 ------ .../comm/ControlLoopStateChangeListener.java | 48 --- .../comm/ControlLoopUpdateListener.java | 47 -- .../intermediary/comm/MessageSender.java | 78 ---- .../intermediary/comm/ParticipantAckListener.java | 67 --- .../comm/ParticipantDeregisterAckListener.java | 48 --- .../intermediary/comm/ParticipantListener.java | 64 --- .../comm/ParticipantMessagePublisher.java | 147 ------- .../comm/ParticipantRegisterAckListener.java | 48 --- .../comm/ParticipantStatusReqListener.java | 47 -- .../comm/ParticipantUpdateListener.java | 47 -- .../intermediary/handler/ControlLoopHandler.java | 454 -------------------- .../handler/IntermediaryActivator.java | 154 ------- .../participant/intermediary/handler/Listener.java | 41 -- .../intermediary/handler/ParticipantHandler.java | 415 ------------------ .../intermediary/handler/Publisher.java | 34 -- .../ParticipantIntermediaryParameters.java | 61 --- .../parameters/ParticipantParameters.java | 26 -- .../impl/ParticipantIntermediaryApiImplTest.java | 103 +++++ .../intermediary/comm/ParticipantCommTest.java | 116 +++++ .../handler/AutomationCompositionHandlerTest.java | 227 ++++++++++ .../handler/DummyParticipantParameters.java | 35 ++ .../handler/IntermediaryActivatorTest.java | 103 +++++ .../handler/ParticipantHandlerTest.java | 176 ++++++++ .../main/parameters/CommonTestData.java | 294 +++++++++++++ .../TestParticipantIntermediaryParameters.java | 67 +++ .../impl/ParticipantIntermediaryApiImplTest.java | 102 ----- .../intermediary/comm/ParticipantCommTest.java | 119 ------ .../handler/ControlLoopHandlerTest.java | 226 ---------- .../handler/DummyParticipantParameters.java | 35 -- .../handler/IntermediaryActivatorTest.java | 103 ----- .../handler/ParticipantHandlerTest.java | 176 -------- .../main/parameters/CommonTestData.java | 293 ------------- .../TestParticipantIntermediaryParameters.java | 67 --- .../providers/TestAutomationCompositions.json | 142 ++++++ .../test/resources/providers/TestControlLoops.json | 142 ------ 272 files changed, 12292 insertions(+), 14382 deletions(-) create mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/Application.java create mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/config/ParticipantConfig.java create mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/config/SecurityConfig.java create mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/exception/HttpWebClientException.java create mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/handler/AutomationCompositionElementHandler.java create mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/models/ConfigRequest.java create mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/models/ConfigurationEntity.java create mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/models/RestParams.java create mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/webclient/AcHttpClient.java create mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/parameters/ParticipantHttpParameters.java delete mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/Application.java delete mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/config/ParticipantConfig.java delete mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/config/SecurityConfig.java delete mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/exception/HttpWebClientException.java delete mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/handler/ControlLoopElementHandler.java delete mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/models/ConfigRequest.java delete mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/models/ConfigurationEntity.java delete mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/models/RestParams.java delete mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/webclient/ClHttpClient.java delete mode 100644 participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/parameters/ParticipantHttpParameters.java create mode 100644 participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/handler/AcElementHandlerTest.java create mode 100644 participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/rest/ActuatorControllerTest.java create mode 100644 participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/utils/CommonActuatorController.java create mode 100644 participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/utils/CommonTestData.java create mode 100644 participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/utils/ToscaUtils.java create mode 100644 participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/webclient/AcHttpClientTest.java delete mode 100644 participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/handler/ClElementHandlerTest.java delete mode 100644 participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/rest/ActuatorControllerTest.java delete mode 100644 participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/utils/CommonActuatorController.java delete mode 100644 participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/utils/CommonTestData.java delete mode 100644 participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/utils/ToscaUtils.java delete mode 100644 participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/webclient/ClHttpClientTest.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/Application.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/ParticipantConfig.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/ParticipantIntermediaryConfig.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/SecurityConfig.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/SpringFoxConfig.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/controller/ChartController.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/exception/ServiceException.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandler.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/HelmClient.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidator.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/models/ChartInfo.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/models/ChartList.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/models/HelmRepository.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/models/InstallationInfo.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/ParticipantK8sParameters.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartService.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartStore.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/Application.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParticipantConfig.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParticipantIntermediaryConfig.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/SecurityConfig.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/SpringFoxConfig.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/controller/ChartController.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/exception/ServiceException.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClient.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/PodStatusValidator.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartInfo.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartList.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/HelmRepository.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/InstallationInfo.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParameters.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartService.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartStore.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandlerTest.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/HelmClientTest.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidatorTest.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/CommonTestData.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/ParticipantK8sParametersTest.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/rest/ActuatorControllerTest.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/rest/ChartControllerTest.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartServiceTest.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartStoreTest.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/utils/CommonActuatorController.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/utils/TestUtils.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandlerTest.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClientTest.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/PodStatusValidatorTest.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/CommonTestData.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParametersTest.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/rest/ActuatorControllerTest.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/rest/ChartControllerTest.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartServiceTest.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartStoreTest.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/utils/CommonActuatorController.java delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/utils/TestUtils.java create mode 100644 participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/PolicyParticipantApplication.java create mode 100644 participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/client/AbstractHttpClient.java create mode 100644 participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/client/PolicyApiHttpClient.java create mode 100644 participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/client/PolicyPapHttpClient.java create mode 100644 participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/config/ParticipantConfig.java create mode 100644 participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/config/SecurityConfig.java create mode 100644 participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandler.java create mode 100644 participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/main/parameters/ParticipantPolicyParameters.java delete mode 100644 participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/PolicyParticipantApplication.java delete mode 100644 participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/client/AbstractHttpClient.java delete mode 100644 participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/client/PolicyApiHttpClient.java delete mode 100644 participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/client/PolicyPapHttpClient.java delete mode 100644 participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/ParticipantConfig.java delete mode 100644 participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/SecurityConfig.java delete mode 100644 participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/ControlLoopElementHandler.java delete mode 100644 participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/ParticipantPolicyParameters.java create mode 100644 participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/endtoend/ParticipantMessagesTest.java create mode 100644 participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandlerTest.java create mode 100644 participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/parameters/CommonTestData.java create mode 100644 participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/parameters/ParticipantPolicyParametersTest.java create mode 100644 participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/rest/ActuatorControllerTest.java create mode 100644 participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/utils/CommonActuatorController.java create mode 100644 participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/utils/TestListenerUtils.java delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/endtoend/ParticipantMessagesTest.java delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/ControlLoopElementHandlerTest.java delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/CommonTestData.java delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/ParticipantPolicyParametersTest.java delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/rest/ActuatorControllerTest.java delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/utils/CommonActuatorController.java delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/utils/TestListenerUtils.java create mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/parameters/TestACParams.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/parameters/TestCLParams.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policies/vCPE.policies.optimization.input.tosca.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.Match.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.Naming.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.Optimization.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.Common.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.common.Blacklist.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.common.Filter.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.common.FrequencyLimiter.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.common.MinMax.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.coordination.FirstBlocksSecond.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.operational.Common.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.operational.common.Apex.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.operational.common.Drools.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.dcae-pm-mapper.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.dcae-pm-subscription-handler.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.dcae-restconfcollector.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.dcaegen2.collectors.datafile.datafile-app-server.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.tcagen2.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.native.Apex.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.native.Drools.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.native.Xacml.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.Resource.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.Service.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.AffinityPolicy.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.DistancePolicy.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.HpaPolicy.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.OptimizationPolicy.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.PciPolicy.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.Vim_fit.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.VnfPolicy.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.service.QueryPolicy.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.service.SubscriberPolicy.yaml create mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/utils/servicetemplates/pm_automation_composition_tosca.yaml delete mode 100644 participant/participant-impl/participant-impl-policy/src/test/resources/utils/servicetemplates/pm_control_loop_tosca.yaml create mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/ParticipantSimulatorApplication.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/AafConfiguration.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/ParticipantConfig.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/SecurityConfig.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/SpringFoxConfig.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/YamlConfiguration.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/handler/AutomationCompositionElementHandler.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/parameters/ParticipantSimulatorParameters.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/AbstractRestController.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/GlobalControllerExceptionHandler.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/ParticipantErrorController.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/ParticipantSimulatorAafFilter.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/simulation/SimulationProvider.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/simulation/rest/SimulationElementController.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/simulation/rest/SimulationParticipantController.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/ParticipantSimulatorApplication.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/AafConfiguration.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/ParticipantConfig.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/SecurityConfig.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/SpringFoxConfig.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/YamlConfiguration.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/handler/ControlLoopElementHandler.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/ParticipantSimulatorParameters.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/AbstractRestController.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/GlobalControllerExceptionHandler.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/ParticipantErrorController.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/ParticipantSimulatorAafFilter.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/SimulationProvider.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationElementController.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationParticipantController.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/endtoend/ParticipantSimulatorTest.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/main/handler/AutomationCompositionElementHandlerTest.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/main/parameters/CommonTestData.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/main/parameters/TestParticipantSimulatorParameters.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/TestListenerUtils.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/endtoend/ParticipantSimulatorTest.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/handler/ControlLoopElementHandlerTest.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/CommonTestData.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/TestParticipantSimulatorParameters.java delete mode 100644 participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/TestListenerUtils.java create mode 100644 participant/participant-impl/participant-impl-simulator/src/test/resources/rest/servicetemplates/pm_automation_composition_tosca.yaml delete mode 100644 participant/participant-impl/participant-impl-simulator/src/test/resources/rest/servicetemplates/pm_control_loop_tosca.yaml create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/AutomationCompositionElementListener.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AutomationCompositionStateChangeListener.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AutomationCompositionUpdateListener.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/MessageSender.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantAckListener.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantDeregisterAckListener.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantListener.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantMessagePublisher.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantRegisterAckListener.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantStatusReqListener.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantUpdateListener.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/IntermediaryActivator.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/Listener.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/Publisher.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/parameters/ParticipantIntermediaryParameters.java create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/parameters/ParticipantParameters.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ControlLoopElementListener.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ControlLoopStateChangeListener.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ControlLoopUpdateListener.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/MessageSender.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantAckListener.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantDeregisterAckListener.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantListener.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantMessagePublisher.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantRegisterAckListener.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantStatusReqListener.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantUpdateListener.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivator.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/Listener.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandler.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/Publisher.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/parameters/ParticipantIntermediaryParameters.java delete mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/parameters/ParticipantParameters.java create mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java create mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantCommTest.java create mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java create mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/DummyParticipantParameters.java create mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/IntermediaryActivatorTest.java create mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.java create mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/CommonTestData.java create mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/TestParticipantIntermediaryParameters.java delete mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java delete mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantCommTest.java delete mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandlerTest.java delete mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/DummyParticipantParameters.java delete mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivatorTest.java delete mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandlerTest.java delete mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/main/parameters/CommonTestData.java delete mode 100644 participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/main/parameters/TestParticipantIntermediaryParameters.java create mode 100644 participant/participant-intermediary/src/test/resources/providers/TestAutomationCompositions.json delete mode 100644 participant/participant-intermediary/src/test/resources/providers/TestControlLoops.json (limited to 'participant') diff --git a/participant/participant-impl/participant-impl-cds/pom.xml b/participant/participant-impl/participant-impl-cds/pom.xml index 0f806a602..0b85867c3 100644 --- a/participant/participant-impl/participant-impl-cds/pom.xml +++ b/participant/participant-impl/participant-impl-cds/pom.xml @@ -30,5 +30,5 @@ policy-clamp-participant-impl-cds ${project.artifactId} - CDS participant, that allows CDS to partake in control loops + CDS participant, that allows CDS to partake in automation compositions diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/Application.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/Application.java new file mode 100644 index 000000000..2f26a8659 --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/Application.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.http; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.ConfigurationPropertiesScan; +import org.springframework.context.annotation.ComponentScan; + +/** + * Starter. + * + */ +// @formatter:off +@SpringBootApplication +@ComponentScan({ + "org.onap.policy.clamp.acm.participant.http", + "org.onap.policy.clamp.acm.participant.intermediary" +}) +@ConfigurationPropertiesScan("org.onap.policy.clamp.acm.participant.http.parameters") +//@formatter:on +public class Application { + /** + * Main class. + * + * @param args args + */ + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/config/ParticipantConfig.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/config/ParticipantConfig.java new file mode 100644 index 000000000..e2b5d1718 --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/config/ParticipantConfig.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.http.config; + +import org.onap.policy.clamp.acm.participant.http.main.handler.AutomationCompositionElementHandler; +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ParticipantConfig { + + /** + * Register AutomationCompositionElementListener. + * + * @param intermediaryApi the ParticipantIntermediaryApi + * @param acElementHandler the AutomationComposition Element Handler + */ + @Autowired + public void registerAutomationCompositionElementListener(ParticipantIntermediaryApi intermediaryApi, + AutomationCompositionElementHandler acElementHandler) { + intermediaryApi.registerAutomationCompositionElementListener(acElementHandler); + acElementHandler.setIntermediaryApi(intermediaryApi); + } +} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/config/SecurityConfig.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/config/SecurityConfig.java new file mode 100644 index 000000000..25a945e7e --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/config/SecurityConfig.java @@ -0,0 +1,45 @@ +/*- + * ========================LICENSE_START================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.http.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Value("${security.enable-csrf:true}") + private boolean csrfEnabled = true; + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.authorizeRequests() + .antMatchers().authenticated() + .anyRequest().authenticated() + .and().httpBasic(); + // @formatter:on + + if (!csrfEnabled) { + http.csrf().disable(); + } + } +} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/exception/HttpWebClientException.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/exception/HttpWebClientException.java new file mode 100644 index 000000000..8978e88ec --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/exception/HttpWebClientException.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.http.main.exception; + + +import org.springframework.web.reactive.function.client.WebClientResponseException; + +public class HttpWebClientException extends WebClientResponseException { + private static final long serialVersionUID = 1L; + + public HttpWebClientException(int statusCode, String statusText) { + super(statusCode, statusText, null, null, null); + } +} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/handler/AutomationCompositionElementHandler.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/handler/AutomationCompositionElementHandler.java new file mode 100644 index 000000000..89c98400e --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/handler/AutomationCompositionElementHandler.java @@ -0,0 +1,180 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021-2022 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.onap.policy.clamp.acm.participant.http.main.handler; + +import java.io.Closeable; +import java.io.IOException; +import java.lang.invoke.MethodHandles; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.stream.Collectors; +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.ValidationException; +import lombok.Setter; +import org.apache.commons.lang3.tuple.Pair; +import org.onap.policy.clamp.acm.participant.http.main.models.ConfigRequest; +import org.onap.policy.clamp.acm.participant.http.main.webclient.AcHttpClient; +import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener; +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; + +/** + * This class handles implementation of automationCompositionElement updates. + */ +@Component +public class AutomationCompositionElementHandler implements AutomationCompositionElementListener, Closeable { + + private static final Coder CODER = new StandardCoder(); + + private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + private final ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + + private final Map> restResponseMap = new ConcurrentHashMap<>(); + + @Setter + private ParticipantIntermediaryApi intermediaryApi; + + /** + * Handle automationCompositionElement statistics. + * + * @param automationCompositionElementId automation composition element id + */ + @Override + public void handleStatistics(UUID automationCompositionElementId) { + // Implementation not needed for http participant + + } + + /** + * Handle a automation composition element state change. + * + * @param automationCompositionElementId the ID of the automation composition element + * @param currentState the current state of the automation composition element + * @param newState the state to which the automation composition element is changing to + * @throws PfModelException in case of a model exception + */ + @Override + public void automationCompositionElementStateChange(ToscaConceptIdentifier automationCompositionId, + UUID automationCompositionElementId, AutomationCompositionState currentState, + AutomationCompositionOrderedState newState) { + switch (newState) { + case UNINITIALISED: + intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, + automationCompositionElementId, newState, AutomationCompositionState.UNINITIALISED, + ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE); + break; + case PASSIVE: + intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, + automationCompositionElementId, newState, AutomationCompositionState.PASSIVE, + ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE); + break; + case RUNNING: + intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, + automationCompositionElementId, newState, AutomationCompositionState.RUNNING, + ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE); + break; + default: + LOGGER.warn("Cannot transition from state {} to state {}", currentState, newState); + break; + } + } + + /** + * Callback method to handle an update on a automation composition element. + * + * @param element the information on the automation composition element + * @param nodeTemplate toscaNodeTemplate + */ + @Override + public void automationCompositionElementUpdate(ToscaConceptIdentifier automationCompositionId, + AutomationCompositionElement element, ToscaNodeTemplate nodeTemplate) { + try { + var configRequest = CODER.convert(nodeTemplate.getProperties(), ConfigRequest.class); + Set> violations = + Validation.buildDefaultValidatorFactory().getValidator().validate(configRequest); + if (violations.isEmpty()) { + invokeHttpClient(configRequest); + List> failedResponseStatus = restResponseMap.values().stream() + .filter(response -> !HttpStatus.valueOf(response.getKey()) + .is2xxSuccessful()).collect(Collectors.toList()); + if (failedResponseStatus.isEmpty()) { + intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(), + AutomationCompositionOrderedState.PASSIVE, AutomationCompositionState.PASSIVE, + ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE); + } else { + LOGGER.error("Error on Invoking the http request: {}", failedResponseStatus); + } + } else { + LOGGER.error("Violations found in the config request parameters: {}", violations); + throw new ValidationException("Constraint violations in the config request"); + } + } catch (CoderException | ValidationException | InterruptedException | ExecutionException e) { + LOGGER.error("Error invoking the http request for the config ", e); + } + } + + /** + * Invoke a runnable thread to execute http requests. + * + * @param configRequest ConfigRequest + */ + public void invokeHttpClient(ConfigRequest configRequest) throws ExecutionException, InterruptedException { + // Invoke runnable thread to execute https requests of all config entities + Future result = executor.submit(new AcHttpClient(configRequest, restResponseMap), restResponseMap); + if (!result.get().isEmpty()) { + LOGGER.debug("Http Request Completed: {}", result.isDone()); + } + } + + /** + * Closes this stream and releases any system resources associated + * with it. If the stream is already closed then invoking this + * method has no effect. + * + * @throws IOException if an I/O error occurs + */ + @Override + public void close() throws IOException { + executor.shutdown(); + } +} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/models/ConfigRequest.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/models/ConfigRequest.java new file mode 100644 index 000000000..c630b3c7c --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/models/ConfigRequest.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.http.main.models; + +import java.util.List; +import java.util.Map; +import javax.validation.Valid; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.ws.rs.DefaultValue; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class ConfigRequest { + + @NotBlank + private String baseUrl; + + @NotNull + private Map httpHeaders; + + @NotNull + @Valid + private List configurationEntities; + + @Min(value = 1) + @DefaultValue("20") + private int uninitializedToPassiveTimeout; + +} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/models/ConfigurationEntity.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/models/ConfigurationEntity.java new file mode 100644 index 000000000..6ac2edb56 --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/models/ConfigurationEntity.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.http.main.models; + +import java.util.List; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +@Data +@AllArgsConstructor +public class ConfigurationEntity { + + @NotNull + private ToscaConceptIdentifier configurationEntityId; + + @NotNull + @Valid + private List restSequence; +} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/models/RestParams.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/models/RestParams.java new file mode 100644 index 000000000..717131f5a --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/models/RestParams.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.http.main.models; + +import java.util.Map; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +@Data +@AllArgsConstructor +public class RestParams { + + @NotNull + private ToscaConceptIdentifier restRequestId; + + @NotNull + private String httpMethod; + + @NotNull + private String path; + + @Min(100) + @Max(599) + private int expectedResponse; + + private Map pathParams; + + private Map queryParams; + + private String body; + +} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/webclient/AcHttpClient.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/webclient/AcHttpClient.java new file mode 100644 index 000000000..563daecd9 --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/webclient/AcHttpClient.java @@ -0,0 +1,135 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.http.main.webclient; + +import java.lang.invoke.MethodHandles; +import java.time.Duration; +import java.util.Map; +import java.util.Objects; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.onap.policy.clamp.acm.participant.http.main.exception.HttpWebClientException; +import org.onap.policy.clamp.acm.participant.http.main.models.ConfigRequest; +import org.onap.policy.clamp.acm.participant.http.main.models.ConfigurationEntity; +import org.onap.policy.clamp.acm.participant.http.main.models.RestParams; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.util.UriComponentsBuilder; +import reactor.core.publisher.Mono; + +public class AcHttpClient implements Runnable { + + private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + private final ConfigRequest configRequest; + + private Map> responseMap; + + /** + * Constructor. + */ + public AcHttpClient(ConfigRequest configRequest, Map> responseMap) { + this.configRequest = configRequest; + this.responseMap = responseMap; + } + + /** + * Runnable to execute http requests. + */ + @Override + public void run() { + + var webClient = WebClient.builder() + .baseUrl(configRequest.getBaseUrl()) + .defaultHeaders(httpHeaders -> httpHeaders.addAll(createHeaders(configRequest))) + .build(); + + for (ConfigurationEntity configurationEntity : configRequest.getConfigurationEntities()) { + LOGGER.info("Executing http requests for the config entity {}", + configurationEntity.getConfigurationEntityId()); + + executeRequest(webClient, configurationEntity); + } + } + + private void executeRequest(WebClient client, ConfigurationEntity configurationEntity) { + + // Iterate the sequence of http requests + for (RestParams request: configurationEntity.getRestSequence()) { + String response = null; + try { + var httpMethod = Objects.requireNonNull(HttpMethod.resolve(request.getHttpMethod())); + var uri = createUriString(request); + LOGGER.info("Executing HTTP request: {} for the Rest request id: {}", httpMethod, + request.getRestRequestId()); + + response = client.method(httpMethod) + .uri(uri) + .body(request.getBody() == null ? BodyInserters.empty() + : BodyInserters.fromValue(request.getBody())) + .exchangeToMono(clientResponse -> + clientResponse.statusCode().value() == request.getExpectedResponse() + ? clientResponse.bodyToMono(String.class) + : Mono.error(new HttpWebClientException(clientResponse.statusCode().value(), + clientResponse.bodyToMono(String.class).toString()))) + .block(Duration.ofMillis(configRequest.getUninitializedToPassiveTimeout() * 1000L)); + + LOGGER.info("HTTP response for the {} request : {}", httpMethod, response); + responseMap.put(request.getRestRequestId(), new ImmutablePair<>(request.getExpectedResponse(), + response)); + + } catch (HttpWebClientException ex) { + LOGGER.error("Error occurred on the HTTP request ", ex); + responseMap.put(request.getRestRequestId(), new ImmutablePair<>(ex.getStatusCode().value(), + ex.getResponseBodyAsString())); + } + } + } + + private HttpHeaders createHeaders(ConfigRequest request) { + var headers = new HttpHeaders(); + for (Map.Entry entry: request.getHttpHeaders().entrySet()) { + headers.add(entry.getKey(), entry.getValue()); + } + return headers; + } + + private String createUriString(RestParams restParams) { + var uriComponentsBuilder = UriComponentsBuilder.fromUriString(restParams.getPath()); + // Add path params if present + if (restParams.getPathParams() != null) { + uriComponentsBuilder.uriVariables(restParams.getPathParams()); + } + // Add query params if present + if (restParams.getQueryParams() != null) { + for (Map.Entry entry : restParams.getQueryParams().entrySet()) { + uriComponentsBuilder.queryParam(entry.getKey(), entry.getValue()); + } + } + return uriComponentsBuilder.build().toUriString(); + } + +} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/parameters/ParticipantHttpParameters.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/parameters/ParticipantHttpParameters.java new file mode 100644 index 000000000..c0f3c6a7a --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/parameters/ParticipantHttpParameters.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.http.parameters; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; +import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantIntermediaryParameters; +import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantParameters; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.validation.annotation.Validated; + +/** + * Class to hold all parameters needed for the http participant. + * + */ +@Validated +@Getter +@Setter +@ConfigurationProperties(prefix = "participant") +public class ParticipantHttpParameters implements ParticipantParameters { + + @NotNull + @Valid + private ParticipantIntermediaryParameters intermediaryParameters; +} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/Application.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/Application.java deleted file mode 100644 index 4f8096502..000000000 --- a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/Application.java +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.http; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.context.properties.ConfigurationPropertiesScan; -import org.springframework.context.annotation.ComponentScan; - -/** - * Starter. - * - */ -@SpringBootApplication -@ComponentScan({"org.onap.policy.clamp.controlloop.participant.http", - "org.onap.policy.clamp.controlloop.participant.intermediary"}) -@ConfigurationPropertiesScan("org.onap.policy.clamp.controlloop.participant.http.parameters") -public class Application { - /** - * Main class. - * - * @param args args - */ - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/config/ParticipantConfig.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/config/ParticipantConfig.java deleted file mode 100644 index ce013a765..000000000 --- a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/config/ParticipantConfig.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.http.config; - -import org.onap.policy.clamp.controlloop.participant.http.main.handler.ControlLoopElementHandler; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class ParticipantConfig { - - /** - * Register ControlLoopElementListener. - * - * @param intermediaryApi the ParticipantIntermediaryApi - * @param clElementHandler the ControlLoop Element Handler - */ - @Autowired - public void registerControlLoopElementListener(ParticipantIntermediaryApi intermediaryApi, - ControlLoopElementHandler clElementHandler) { - intermediaryApi.registerControlLoopElementListener(clElementHandler); - clElementHandler.setIntermediaryApi(intermediaryApi); - } -} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/config/SecurityConfig.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/config/SecurityConfig.java deleted file mode 100644 index 499bbe153..000000000 --- a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/config/SecurityConfig.java +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.http.config; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@Configuration -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Value("${security.enable-csrf:true}") - private boolean csrfEnabled = true; - - @Override - protected void configure(HttpSecurity http) throws Exception { - // @formatter:off - http.authorizeRequests() - .antMatchers().authenticated() - .anyRequest().authenticated() - .and().httpBasic(); - // @formatter:on - - if (!csrfEnabled) { - http.csrf().disable(); - } - } -} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/exception/HttpWebClientException.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/exception/HttpWebClientException.java deleted file mode 100644 index 6b27700c4..000000000 --- a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/exception/HttpWebClientException.java +++ /dev/null @@ -1,33 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.http.main.exception; - - -import org.springframework.web.reactive.function.client.WebClientResponseException; - -public class HttpWebClientException extends WebClientResponseException { - private static final long serialVersionUID = 1L; - - public HttpWebClientException(int statusCode, String statusText) { - super(statusCode, statusText, null, null, null); - } -} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/handler/ControlLoopElementHandler.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/handler/ControlLoopElementHandler.java deleted file mode 100644 index 69d8c750a..000000000 --- a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/handler/ControlLoopElementHandler.java +++ /dev/null @@ -1,178 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 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.onap.policy.clamp.controlloop.participant.http.main.handler; - -import java.io.Closeable; -import java.io.IOException; -import java.lang.invoke.MethodHandles; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.stream.Collectors; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.ValidationException; -import lombok.Setter; -import org.apache.commons.lang3.tuple.Pair; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; -import org.onap.policy.clamp.controlloop.participant.http.main.models.ConfigRequest; -import org.onap.policy.clamp.controlloop.participant.http.main.webclient.ClHttpClient; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Component; - -/** - * This class handles implementation of controlLoopElement updates. - */ -@Component -public class ControlLoopElementHandler implements ControlLoopElementListener, Closeable { - - private static final Coder CODER = new StandardCoder(); - - private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - - private ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); - - private Map> restResponseMap = new ConcurrentHashMap<>(); - - @Setter - private ParticipantIntermediaryApi intermediaryApi; - - /** - * Handle controlLoopElement statistics. - * - * @param controlLoopElementId controlloop element id - */ - @Override - public void handleStatistics(UUID controlLoopElementId) throws PfModelException { - // Implementation not needed for http participant - - } - - /** - * Handle a control loop element state change. - * - * @param controlLoopElementId the ID of the control loop element - * @param currentState the current state of the control loop element - * @param newState the state to which the control loop element is changing to - * @throws PfModelException in case of a model exception - */ - @Override - public void controlLoopElementStateChange(ToscaConceptIdentifier controlLoopId, UUID controlLoopElementId, - ControlLoopState currentState, ControlLoopOrderedState newState) throws PfModelException { - switch (newState) { - case UNINITIALISED: - intermediaryApi.updateControlLoopElementState(controlLoopId, - controlLoopElementId, newState, ControlLoopState.UNINITIALISED, - ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); - break; - case PASSIVE: - intermediaryApi.updateControlLoopElementState(controlLoopId, - controlLoopElementId, newState, ControlLoopState.PASSIVE, - ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); - break; - case RUNNING: - intermediaryApi.updateControlLoopElementState(controlLoopId, - controlLoopElementId, newState, ControlLoopState.RUNNING, - ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); - break; - default: - LOGGER.warn("Cannot transition from state {} to state {}", currentState, newState); - break; - } - } - - /** - * Callback method to handle an update on a control loop element. - * - * @param element the information on the control loop element - * @param nodeTemplate toscaNodeTemplate - */ - @Override - public void controlLoopElementUpdate(ToscaConceptIdentifier controlLoopId, ControlLoopElement element, - ToscaNodeTemplate nodeTemplate) { - try { - var configRequest = CODER.convert(nodeTemplate.getProperties(), ConfigRequest.class); - Set> violations = Validation.buildDefaultValidatorFactory() - .getValidator().validate(configRequest); - if (violations.isEmpty()) { - invokeHttpClient(configRequest); - List> failedResponseStatus = restResponseMap.values().stream() - .filter(response -> !HttpStatus.valueOf(response.getKey()) - .is2xxSuccessful()).collect(Collectors.toList()); - if (failedResponseStatus.isEmpty()) { - intermediaryApi.updateControlLoopElementState(controlLoopId, element.getId(), - ControlLoopOrderedState.PASSIVE, ControlLoopState.PASSIVE, - ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); - } else { - LOGGER.error("Error on Invoking the http request: {}", failedResponseStatus); - } - } else { - LOGGER.error("Violations found in the config request parameters: {}", violations); - throw new ValidationException("Constraint violations in the config request"); - } - } catch (CoderException | ValidationException | InterruptedException | ExecutionException e) { - LOGGER.error("Error invoking the http request for the config ", e); - } - } - - /** - * Invoke a runnable thread to execute http requests. - * @param configRequest ConfigRequest - */ - public void invokeHttpClient(ConfigRequest configRequest) throws ExecutionException, InterruptedException { - // Invoke runnable thread to execute https requests of all config entities - Future result = executor.submit(new ClHttpClient(configRequest, restResponseMap), restResponseMap); - if (!result.get().isEmpty()) { - LOGGER.debug("Http Request Completed: {}", result.isDone()); - } - } - - /** - * Closes this stream and releases any system resources associated - * with it. If the stream is already closed then invoking this - * method has no effect. - * - * @throws IOException if an I/O error occurs - */ - @Override - public void close() throws IOException { - executor.shutdown(); - } -} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/models/ConfigRequest.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/models/ConfigRequest.java deleted file mode 100644 index 87cab88a7..000000000 --- a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/models/ConfigRequest.java +++ /dev/null @@ -1,51 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.http.main.models; - -import java.util.List; -import java.util.Map; -import javax.validation.Valid; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.ws.rs.DefaultValue; -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor -public class ConfigRequest { - - @NotBlank - private String baseUrl; - - @NotNull - private Map httpHeaders; - - @NotNull - @Valid - private List configurationEntities; - - @Min(value = 1) - @DefaultValue("20") - private int uninitializedToPassiveTimeout; - -} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/models/ConfigurationEntity.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/models/ConfigurationEntity.java deleted file mode 100644 index 8703a9d21..000000000 --- a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/models/ConfigurationEntity.java +++ /dev/null @@ -1,40 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.http.main.models; - -import java.util.List; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Data; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; - -@Data -@AllArgsConstructor -public class ConfigurationEntity { - - @NotNull - private ToscaConceptIdentifier configurationEntityId; - - @NotNull - @Valid - private List restSequence; -} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/models/RestParams.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/models/RestParams.java deleted file mode 100644 index fc4e02897..000000000 --- a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/models/RestParams.java +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.http.main.models; - -import java.util.Map; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Data; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; - -@Data -@AllArgsConstructor -public class RestParams { - - @NotNull - private ToscaConceptIdentifier restRequestId; - - @NotNull - private String httpMethod; - - @NotNull - private String path; - - @Min(100) - @Max(599) - private int expectedResponse; - - private Map pathParams; - - private Map queryParams; - - private String body; - -} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/webclient/ClHttpClient.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/webclient/ClHttpClient.java deleted file mode 100644 index 0e0ea557e..000000000 --- a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/webclient/ClHttpClient.java +++ /dev/null @@ -1,135 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.http.main.webclient; - -import java.lang.invoke.MethodHandles; -import java.time.Duration; -import java.util.Map; -import java.util.Objects; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; -import org.onap.policy.clamp.controlloop.participant.http.main.exception.HttpWebClientException; -import org.onap.policy.clamp.controlloop.participant.http.main.models.ConfigRequest; -import org.onap.policy.clamp.controlloop.participant.http.main.models.ConfigurationEntity; -import org.onap.policy.clamp.controlloop.participant.http.main.models.RestParams; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.web.reactive.function.BodyInserters; -import org.springframework.web.reactive.function.client.WebClient; -import org.springframework.web.util.UriComponentsBuilder; -import reactor.core.publisher.Mono; - -public class ClHttpClient implements Runnable { - - private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - - private final ConfigRequest configRequest; - - private Map> responseMap; - - /** - * Constructor. - */ - public ClHttpClient(ConfigRequest configRequest, Map> responseMap) { - this.configRequest = configRequest; - this.responseMap = responseMap; - } - - /** - * Runnable to execute http requests. - */ - @Override - public void run() { - - var webClient = WebClient.builder() - .baseUrl(configRequest.getBaseUrl()) - .defaultHeaders(httpHeaders -> httpHeaders.addAll(createHeaders(configRequest))) - .build(); - - for (ConfigurationEntity configurationEntity : configRequest.getConfigurationEntities()) { - LOGGER.info("Executing http requests for the config entity {}", - configurationEntity.getConfigurationEntityId()); - - executeRequest(webClient, configurationEntity); - } - } - - private void executeRequest(WebClient client, ConfigurationEntity configurationEntity) { - - // Iterate the sequence of http requests - for (RestParams request: configurationEntity.getRestSequence()) { - String response = null; - try { - var httpMethod = Objects.requireNonNull(HttpMethod.resolve(request.getHttpMethod())); - var uri = createUriString(request); - LOGGER.info("Executing HTTP request: {} for the Rest request id: {}", httpMethod, - request.getRestRequestId()); - - response = client.method(httpMethod) - .uri(uri) - .body(request.getBody() == null ? BodyInserters.empty() - : BodyInserters.fromValue(request.getBody())) - .exchangeToMono(clientResponse -> - clientResponse.statusCode().value() == request.getExpectedResponse() - ? clientResponse.bodyToMono(String.class) - : Mono.error(new HttpWebClientException(clientResponse.statusCode().value(), - clientResponse.bodyToMono(String.class).toString()))) - .block(Duration.ofMillis(configRequest.getUninitializedToPassiveTimeout() * 1000L)); - - LOGGER.info("HTTP response for the {} request : {}", httpMethod, response); - responseMap.put(request.getRestRequestId(), new ImmutablePair<>(request.getExpectedResponse(), - response)); - - } catch (HttpWebClientException ex) { - LOGGER.error("Error occurred on the HTTP request ", ex); - responseMap.put(request.getRestRequestId(), new ImmutablePair<>(ex.getStatusCode().value(), - ex.getResponseBodyAsString())); - } - } - } - - private HttpHeaders createHeaders(ConfigRequest request) { - var headers = new HttpHeaders(); - for (Map.Entry entry: request.getHttpHeaders().entrySet()) { - headers.add(entry.getKey(), entry.getValue()); - } - return headers; - } - - private String createUriString(RestParams restParams) { - var uriComponentsBuilder = UriComponentsBuilder.fromUriString(restParams.getPath()); - // Add path params if present - if (restParams.getPathParams() != null) { - uriComponentsBuilder.uriVariables(restParams.getPathParams()); - } - // Add query params if present - if (restParams.getQueryParams() != null) { - for (Map.Entry entry : restParams.getQueryParams().entrySet()) { - uriComponentsBuilder.queryParam(entry.getKey(), entry.getValue()); - } - } - return uriComponentsBuilder.build().toUriString(); - } - -} diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/parameters/ParticipantHttpParameters.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/parameters/ParticipantHttpParameters.java deleted file mode 100644 index 62bbd7593..000000000 --- a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/parameters/ParticipantHttpParameters.java +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.http.parameters; - -import javax.validation.Valid; -import javax.validation.constraints.NotNull; -import lombok.Getter; -import lombok.Setter; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.validation.annotation.Validated; - -/** - * Class to hold all parameters needed for the http participant. - * - */ -@Validated -@Getter -@Setter -@ConfigurationProperties(prefix = "participant") -public class ParticipantHttpParameters implements ParticipantParameters { - - @NotNull - @Valid - private ParticipantIntermediaryParameters intermediaryParameters; - -} diff --git a/participant/participant-impl/participant-impl-http/src/main/resources/config/application.yaml b/participant/participant-impl/participant-impl-http/src/main/resources/config/application.yaml index df0ad7df3..8a3d0fbf2 100644 --- a/participant/participant-impl/participant-impl-http/src/main/resources/config/application.yaml +++ b/participant/participant-impl/participant-impl-http/src/main/resources/config/application.yaml @@ -13,17 +13,17 @@ participant: name: HttpParticipant0 version: 1.0.0 participantType: - name: org.onap.k8s.controlloop.HttpControlLoopParticipant + name: org.onap.policy.clamp.acm.HttpParticipant version: 2.3.4 - clampControlLoopTopics: + clampAutomationCompositionTopics: topicSources: - - topic: POLICY-CLRUNTIME-PARTICIPANT + - topic: POLICY-ACRUNTIME-PARTICIPANT servers: - ${topicServer:message-router} topicCommInfrastructure: dmaap fetchTimeout: 15000 topicSinks: - - topic: POLICY-CLRUNTIME-PARTICIPANT + - topic: POLICY-ACRUNTIME-PARTICIPANT servers: - ${topicServer:message-router} topicCommInfrastructure: dmaap @@ -35,4 +35,4 @@ management: server: port: 8084 servlet: - context-path: /onap/httpparticipant + context-path: /onap/policy/clamp/acm/httpparticipant diff --git a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/handler/AcElementHandlerTest.java b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/handler/AcElementHandlerTest.java new file mode 100644 index 000000000..fbb689448 --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/handler/AcElementHandlerTest.java @@ -0,0 +1,106 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.http.handler; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; + +import java.io.IOException; +import java.util.Map; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.onap.policy.clamp.acm.participant.http.main.handler.AutomationCompositionElementHandler; +import org.onap.policy.clamp.acm.participant.http.main.models.ConfigRequest; +import org.onap.policy.clamp.acm.participant.http.utils.CommonTestData; +import org.onap.policy.clamp.acm.participant.http.utils.ToscaUtils; +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +class AcElementHandlerTest { + + @InjectMocks + @Spy + private AutomationCompositionElementHandler automationCompositionElementHandler = + new AutomationCompositionElementHandler(); + + @Mock + private ParticipantIntermediaryApi participantIntermediaryApi; + + private CommonTestData commonTestData = new CommonTestData(); + + private static ToscaServiceTemplate serviceTemplate; + private static final String HTTP_AUTOMATION_COMPOSITION_ELEMENT = + "org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement"; + + @BeforeAll + static void init() throws CoderException { + serviceTemplate = ToscaUtils.readAutomationCompositionFromTosca(); + } + + @Test + void test_automationCompositionElementeStateChange() throws IOException { + var automationCompositionId = commonTestData.getAutomationCompositionId(); + var element = commonTestData.getAutomationCompositionElement(); + var automationCompositionElementId = element.getId(); + + var config = Mockito.mock(ConfigRequest.class); + assertDoesNotThrow(() -> automationCompositionElementHandler.invokeHttpClient(config)); + + assertDoesNotThrow(() -> automationCompositionElementHandler.automationCompositionElementStateChange( + automationCompositionId, automationCompositionElementId, AutomationCompositionState.PASSIVE, + AutomationCompositionOrderedState.PASSIVE)); + + assertDoesNotThrow(() -> automationCompositionElementHandler.automationCompositionElementStateChange( + automationCompositionId, automationCompositionElementId, AutomationCompositionState.PASSIVE, + AutomationCompositionOrderedState.UNINITIALISED)); + + assertDoesNotThrow(() -> automationCompositionElementHandler.automationCompositionElementStateChange( + automationCompositionId, automationCompositionElementId, AutomationCompositionState.PASSIVE, + AutomationCompositionOrderedState.RUNNING)); + + automationCompositionElementHandler.close(); + } + + @Test + void test_AutomationCompositionElementUpdate() throws Exception { + doNothing().when(automationCompositionElementHandler).invokeHttpClient(any()); + AutomationCompositionElement element = commonTestData.getAutomationCompositionElement(); + + Map nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates(); + + assertDoesNotThrow(() -> automationCompositionElementHandler.automationCompositionElementUpdate( + commonTestData.getAutomationCompositionId(), element, + nodeTemplatesMap.get(HTTP_AUTOMATION_COMPOSITION_ELEMENT))); + } +} diff --git a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/rest/ActuatorControllerTest.java b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/rest/ActuatorControllerTest.java new file mode 100644 index 000000000..f0a465fa2 --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/rest/ActuatorControllerTest.java @@ -0,0 +1,92 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.http.rest; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import javax.ws.rs.client.Invocation; +import javax.ws.rs.core.Response; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.onap.policy.clamp.acm.participant.http.utils.CommonActuatorController; +import org.springframework.boot.test.autoconfigure.actuate.metrics.AutoConfigureMetrics; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@AutoConfigureMetrics +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@TestPropertySource(locations = {"classpath:application_test.properties"}) +class ActuatorControllerTest extends CommonActuatorController { + + private static final String HEALTH_ENDPOINT = "health"; + private static final String METRICS_ENDPOINT = "metrics"; + private static final String PROMETHEUS_ENDPOINT = "prometheus"; + + @LocalServerPort + private int randomServerPort; + + @BeforeEach + public void setUpPort() { + super.setHttpPrefix(randomServerPort); + } + + @Test + void testGetHealth_Unauthorized() throws Exception { + assertUnauthorizedActGet(HEALTH_ENDPOINT); + } + + @Test + void testGetMetrics_Unauthorized() throws Exception { + assertUnauthorizedActGet(METRICS_ENDPOINT); + } + + @Test + void testGetPrometheus_Unauthorized() throws Exception { + assertUnauthorizedActGet(PROMETHEUS_ENDPOINT); + } + + @Test + void testGetHealth() throws Exception { + Invocation.Builder invocationBuilder = super.sendActRequest(HEALTH_ENDPOINT); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + } + + @Test + void testGetMetrics() throws Exception { + Invocation.Builder invocationBuilder = super.sendActRequest(METRICS_ENDPOINT); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + } + + @Test + void testGePrometheus() throws Exception { + Invocation.Builder invocationBuilder = super.sendActRequest(PROMETHEUS_ENDPOINT); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + } + +} diff --git a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/utils/CommonActuatorController.java b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/utils/CommonActuatorController.java new file mode 100644 index 000000000..cfe3ec2c3 --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/utils/CommonActuatorController.java @@ -0,0 +1,114 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.http.utils; + +import static org.junit.Assert.assertEquals; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.glassfish.jersey.client.ClientProperties; +import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; +import org.onap.policy.common.gson.GsonMessageBodyHandler; +import org.onap.policy.common.utils.network.NetworkUtil; + +/** + * Class to perform Rest unit tests. + * + */ +public class CommonActuatorController { + + public static final String SELF = NetworkUtil.getHostname(); + public static final String CONTEXT_PATH = "onap/policy/clamp/acm/httpparticipant"; + public static final String ACTUATOR_ENDPOINT = CONTEXT_PATH + "/actuator/"; + + private static String httpPrefix; + + /** + * Sends a request to an actuator endpoint. + * + * @param endpoint the target endpoint + * @return a request builder + * @throws Exception if an error occurs + */ + protected Invocation.Builder sendActRequest(final String endpoint) throws Exception { + return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + endpoint, true); + } + + /** + * Sends a request to an actuator endpoint, without any authorization header. + * + * @param endpoint the target endpoint + * @return a request builder + * @throws Exception if an error occurs + */ + protected Invocation.Builder sendNoAuthActRequest(final String endpoint) throws Exception { + return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + endpoint, false); + } + + /** + * Sends a request to a fully qualified endpoint. + * + * @param fullyQualifiedEndpoint the fully qualified target endpoint + * @param includeAuth if authorization header should be included + * @return a request builder + * @throws Exception if an error occurs + */ + protected Invocation.Builder sendFqeRequest(final String fullyQualifiedEndpoint, boolean includeAuth) + throws Exception { + final Client client = ClientBuilder.newBuilder().build(); + + client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true"); + client.register(GsonMessageBodyHandler.class); + + if (includeAuth) { + client.register(HttpAuthenticationFeature.basic("participantUser", "zb!XztG34")); + } + + final WebTarget webTarget = client.target(fullyQualifiedEndpoint); + + return webTarget.request(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN); + } + + /** + * Assert that GET call to actuator endpoint is Unauthorized. + * + * @param endPoint the endpoint + * @throws Exception if an error occurs + */ + protected void assertUnauthorizedActGet(final String endPoint) throws Exception { + Response rawresp = sendNoAuthActRequest(endPoint).buildGet().invoke(); + assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus()); + } + + /** + * Set Up httpPrefix. + * + * @param port the port + */ + protected void setHttpPrefix(int port) { + httpPrefix = "http://" + SELF + ":" + port + "/"; + } + +} diff --git a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/utils/CommonTestData.java b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/utils/CommonTestData.java new file mode 100644 index 000000000..010d29a66 --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/utils/CommonTestData.java @@ -0,0 +1,137 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.http.utils; + +import java.util.List; +import java.util.Map; +import java.util.UUID; +import org.onap.policy.clamp.acm.participant.http.main.models.ConfigurationEntity; +import org.onap.policy.clamp.acm.participant.http.main.models.RestParams; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +public class CommonTestData { + + private static final String TEST_KEY_NAME = + "org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement"; + + /** + * Get a automationComposition Element. + * + * @return automationCompositionElement object + */ + public AutomationCompositionElement getAutomationCompositionElement() { + AutomationCompositionElement element = new AutomationCompositionElement(); + element.setId(UUID.randomUUID()); + element.setDefinition(new ToscaConceptIdentifier(TEST_KEY_NAME, "1.0.1")); + element.setOrderedState(AutomationCompositionOrderedState.PASSIVE); + return element; + } + + /** + * Get query params. + * + * @return Map of query params + */ + public Map getQueryParams() { + return Map.of("name", "dummy", "version", "1.0"); + } + + /** + * Get path params. + * + * @return Map of path params + */ + public Map getPathParams() { + return Map.of("id", "123", "name", "dummy"); + } + + /** + * Rest params with GET request. + * + * @return RestParams obj + */ + public RestParams restParamsWithGet() { + return new RestParams(new ToscaConceptIdentifier("getRequest", "1.0"), "GET", "get", 200, null, + getQueryParams(), null); + } + + /** + * Rest params with POST request. + * + * @return RestParams obj + */ + public RestParams restParamsWithPost() { + return new RestParams(new ToscaConceptIdentifier("postRequest", "1.0"), "POST", "post", 200, null, + getQueryParams(), "Test body"); + } + + /** + * Rest params with POST request. + * + * @return RestParams obj + */ + public RestParams restParamsWithInvalidPost() { + return new RestParams(new ToscaConceptIdentifier("postRequest", "1.0"), "POST", "post/{id}/{name}", 200, + getPathParams(), getQueryParams(), "Test body"); + } + + /** + * Get invalid configuration entity. + * + * @return ConfigurationEntity obj + */ + public ConfigurationEntity getInvalidConfigurationEntity() { + return new ConfigurationEntity(new ToscaConceptIdentifier("config1", "1.0.1"), + List.of(restParamsWithGet(), restParamsWithInvalidPost())); + } + + /** + * Get configuration entity. + * + * @return ConfigurationEntity obj + */ + public ConfigurationEntity getConfigurationEntity() { + return new ConfigurationEntity(new ToscaConceptIdentifier("config1", "1.0.1"), + List.of(restParamsWithGet(), restParamsWithPost())); + } + + /** + * Get automation composition id. + * + * @return ToscaConceptIdentifier automationCompositionId + */ + public ToscaConceptIdentifier getAutomationCompositionId() { + return new ToscaConceptIdentifier("PMSHInstance0", "1.0.0"); + } + + /** + * Get headers for config request. + * + * @return Map of headers + */ + public Map getHeaders() { + return Map.of("Content-Type", "application/json", "Accept", "application/json"); + } + +} diff --git a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/utils/ToscaUtils.java b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/utils/ToscaUtils.java new file mode 100644 index 000000000..9e46212bf --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/utils/ToscaUtils.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.http.utils; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.onap.policy.common.utils.coder.YamlJsonTranslator; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; + +/** + * Util class for Test scope. + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class ToscaUtils { + + private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator(); + private static final String TOSCA_TEMPLATE_YAML = "src/test/resources/HttpParticipantConfig.yaml"; + + + /** + * Read a service template yaml. + * @return ToscaServiceTemplate + */ + public static ToscaServiceTemplate readAutomationCompositionFromTosca() { + return serializeAutomationCompositionYaml(TOSCA_TEMPLATE_YAML); + } + + private static ToscaServiceTemplate serializeAutomationCompositionYaml(String automationCompositionFilePath) { + String automationCompositionString = ResourceUtils.getResourceAsString(automationCompositionFilePath); + return yamlTranslator.fromYaml(automationCompositionString, ToscaServiceTemplate.class); + } +} diff --git a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/webclient/AcHttpClientTest.java b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/webclient/AcHttpClientTest.java new file mode 100644 index 000000000..44ef50848 --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/webclient/AcHttpClientTest.java @@ -0,0 +1,129 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.http.webclient; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.ws.rs.core.MediaType; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockserver.integration.ClientAndServer; +import org.mockserver.model.Parameter; +import org.onap.policy.clamp.acm.participant.http.main.models.ConfigRequest; +import org.onap.policy.clamp.acm.participant.http.main.models.ConfigurationEntity; +import org.onap.policy.clamp.acm.participant.http.main.webclient.AcHttpClient; +import org.onap.policy.clamp.acm.participant.http.utils.CommonTestData; +import org.onap.policy.common.utils.network.NetworkUtil; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +class AcHttpClientTest { + + private static CommonTestData commonTestData; + + private static int mockServerPort; + + private String testMockUrl = "http://localhost"; + + private Map> responseMap = new HashMap<>(); + + private static ClientAndServer mockServer; + + /** + * Set up Mock server. + */ + @BeforeAll + static void setUpMockServer() throws IOException { + mockServerPort = NetworkUtil.allocPort(); + mockServer = ClientAndServer.startClientAndServer(mockServerPort); + commonTestData = new CommonTestData(); + List queryParams = new ArrayList<>(); + commonTestData.getQueryParams().forEach((k, v) -> queryParams.add(new Parameter(k, v))); + + mockServer.when(request().withMethod("GET").withPath("/get") + .withHeader("Content-type", MediaType.APPLICATION_JSON) + .withHeader("Accept", MediaType.APPLICATION_JSON).withQueryStringParameters(queryParams)) + .respond(response().withBody("dummy body").withStatusCode(200) + .withHeader("Content-Type", MediaType.APPLICATION_JSON)); + + mockServer.when(request().withMethod("POST").withPath("/post") + .withHeader("Content-type", MediaType.APPLICATION_JSON) + .withHeader("Accept", MediaType.APPLICATION_JSON).withQueryStringParameters(queryParams) + .withBody("Test body")) + .respond(response().withStatusCode(200)); + } + + @AfterAll + public static void stopServer() { + mockServer.stop(); + mockServer = null; + } + + + @Test + void test_validRequest() { + //Add valid rest requests POST, GET + ConfigurationEntity configurationEntity = commonTestData.getConfigurationEntity(); + + Map headers = commonTestData.getHeaders(); + ConfigRequest configRequest = new ConfigRequest(testMockUrl + ":" + mockServerPort, headers, + List.of(configurationEntity), 10); + + AcHttpClient client = new AcHttpClient(configRequest, responseMap); + assertDoesNotThrow(client::run); + assertThat(responseMap).hasSize(2).containsKey(commonTestData + .restParamsWithGet().getRestRequestId()); + + Pair restResponseMap = responseMap.get(commonTestData + .restParamsWithGet().getRestRequestId()); + assertThat(restResponseMap.getKey()).isEqualTo(200); + } + + @Test + void test_invalidRequest() { + //Add rest requests Invalid POST, Valid GET + ConfigurationEntity configurationEntity = commonTestData.getInvalidConfigurationEntity(); + + Map headers = commonTestData.getHeaders(); + ConfigRequest configRequest = new ConfigRequest(testMockUrl + ":" + mockServerPort, headers, + List.of(configurationEntity), 10); + + AcHttpClient client = new AcHttpClient(configRequest, responseMap); + assertDoesNotThrow(client::run); + assertThat(responseMap).hasSize(2).containsKey(commonTestData + .restParamsWithGet().getRestRequestId()); + Pair response = responseMap + .get(commonTestData.restParamsWithInvalidPost().getRestRequestId()); + assertThat(response.getKey()).isEqualTo(404); + } +} diff --git a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/handler/ClElementHandlerTest.java b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/handler/ClElementHandlerTest.java deleted file mode 100644 index 08f008ef3..000000000 --- a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/handler/ClElementHandlerTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 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.onap.policy.clamp.controlloop.participant.http.handler; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; - -import java.io.IOException; -import java.util.Map; -import java.util.concurrent.ExecutionException; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.Spy; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; -import org.onap.policy.clamp.controlloop.participant.http.main.handler.ControlLoopElementHandler; -import org.onap.policy.clamp.controlloop.participant.http.main.models.ConfigRequest; -import org.onap.policy.clamp.controlloop.participant.http.utils.CommonTestData; -import org.onap.policy.clamp.controlloop.participant.http.utils.ToscaUtils; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; -import org.springframework.test.context.junit.jupiter.SpringExtension; - - -@ExtendWith(SpringExtension.class) -class ClElementHandlerTest { - - @InjectMocks - @Spy - private ControlLoopElementHandler controlLoopElementHandler = new ControlLoopElementHandler(); - - @Mock - private ParticipantIntermediaryApi participantIntermediaryApi; - - private CommonTestData commonTestData = new CommonTestData(); - - private static ToscaServiceTemplate serviceTemplate; - private static final String HTTP_CONTROL_LOOP_ELEMENT = - "org.onap.domain.database.Http_PMSHMicroserviceControlLoopElement"; - - @BeforeAll - static void init() throws CoderException { - serviceTemplate = ToscaUtils.readControlLoopFromTosca(); - } - - @Test - void test_controlLoopElementeStateChange() throws IOException { - var controlLoopId = commonTestData.getControlLoopId(); - var element = commonTestData.getControlLoopElement(); - var controlLoopElementId = element.getId(); - - var config = Mockito.mock(ConfigRequest.class); - assertDoesNotThrow(() -> controlLoopElementHandler.invokeHttpClient(config)); - - assertDoesNotThrow(() -> controlLoopElementHandler - .controlLoopElementStateChange(controlLoopId, - controlLoopElementId, ControlLoopState.PASSIVE, ControlLoopOrderedState.PASSIVE)); - - assertDoesNotThrow(() -> controlLoopElementHandler - .controlLoopElementStateChange(controlLoopId, - controlLoopElementId, ControlLoopState.PASSIVE, ControlLoopOrderedState.UNINITIALISED)); - - assertDoesNotThrow(() -> controlLoopElementHandler - .controlLoopElementStateChange(controlLoopId, - controlLoopElementId, ControlLoopState.PASSIVE, ControlLoopOrderedState.RUNNING)); - - controlLoopElementHandler.close(); - } - - @Test - void test_ControlLoopElementUpdate() throws ExecutionException, InterruptedException { - doNothing().when(controlLoopElementHandler).invokeHttpClient(any()); - ControlLoopElement element = commonTestData.getControlLoopElement(); - - Map nodeTemplatesMap = - serviceTemplate.getToscaTopologyTemplate().getNodeTemplates(); - - assertDoesNotThrow(() -> controlLoopElementHandler - .controlLoopElementUpdate(commonTestData.getControlLoopId(), element, - nodeTemplatesMap.get(HTTP_CONTROL_LOOP_ELEMENT))); - } -} diff --git a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/rest/ActuatorControllerTest.java b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/rest/ActuatorControllerTest.java deleted file mode 100644 index 8efff8f6a..000000000 --- a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/rest/ActuatorControllerTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.http.rest; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import javax.ws.rs.client.Invocation; -import javax.ws.rs.core.Response; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.onap.policy.clamp.controlloop.participant.http.utils.CommonActuatorController; -import org.springframework.boot.test.autoconfigure.actuate.metrics.AutoConfigureMetrics; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@AutoConfigureMetrics -@ExtendWith(SpringExtension.class) -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -@TestPropertySource(locations = {"classpath:application_test.properties"}) -class ActuatorControllerTest extends CommonActuatorController { - - private static final String HEALTH_ENDPOINT = "health"; - private static final String METRICS_ENDPOINT = "metrics"; - private static final String PROMETHEUS_ENDPOINT = "prometheus"; - - @LocalServerPort - private int randomServerPort; - - @BeforeEach - public void setUpPort() { - super.setHttpPrefix(randomServerPort); - } - - @Test - void testGetHealth_Unauthorized() throws Exception { - assertUnauthorizedActGet(HEALTH_ENDPOINT); - } - - @Test - void testGetMetrics_Unauthorized() throws Exception { - assertUnauthorizedActGet(METRICS_ENDPOINT); - } - - @Test - void testGetPrometheus_Unauthorized() throws Exception { - assertUnauthorizedActGet(PROMETHEUS_ENDPOINT); - } - - @Test - void testGetHealth() throws Exception { - Invocation.Builder invocationBuilder = super.sendActRequest(HEALTH_ENDPOINT); - Response rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); - } - - @Test - void testGetMetrics() throws Exception { - Invocation.Builder invocationBuilder = super.sendActRequest(METRICS_ENDPOINT); - Response rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); - } - - @Test - void testGePrometheus() throws Exception { - Invocation.Builder invocationBuilder = super.sendActRequest(PROMETHEUS_ENDPOINT); - Response rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); - } - -} diff --git a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/utils/CommonActuatorController.java b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/utils/CommonActuatorController.java deleted file mode 100644 index 5ebce8126..000000000 --- a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/utils/CommonActuatorController.java +++ /dev/null @@ -1,114 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.http.utils; - -import static org.junit.Assert.assertEquals; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Invocation; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import org.glassfish.jersey.client.ClientProperties; -import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; -import org.onap.policy.common.gson.GsonMessageBodyHandler; -import org.onap.policy.common.utils.network.NetworkUtil; - -/** - * Class to perform Rest unit tests. - * - */ -public class CommonActuatorController { - - public static final String SELF = NetworkUtil.getHostname(); - public static final String CONTEXT_PATH = "onap/httpparticipant"; - public static final String ACTUATOR_ENDPOINT = CONTEXT_PATH + "/actuator/"; - - private static String httpPrefix; - - /** - * Sends a request to an actuator endpoint. - * - * @param endpoint the target endpoint - * @return a request builder - * @throws Exception if an error occurs - */ - protected Invocation.Builder sendActRequest(final String endpoint) throws Exception { - return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + endpoint, true); - } - - /** - * Sends a request to an actuator endpoint, without any authorization header. - * - * @param endpoint the target endpoint - * @return a request builder - * @throws Exception if an error occurs - */ - protected Invocation.Builder sendNoAuthActRequest(final String endpoint) throws Exception { - return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + endpoint, false); - } - - /** - * Sends a request to a fully qualified endpoint. - * - * @param fullyQualifiedEndpoint the fully qualified target endpoint - * @param includeAuth if authorization header should be included - * @return a request builder - * @throws Exception if an error occurs - */ - protected Invocation.Builder sendFqeRequest(final String fullyQualifiedEndpoint, boolean includeAuth) - throws Exception { - final Client client = ClientBuilder.newBuilder().build(); - - client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true"); - client.register(GsonMessageBodyHandler.class); - - if (includeAuth) { - client.register(HttpAuthenticationFeature.basic("participantUser", "zb!XztG34")); - } - - final WebTarget webTarget = client.target(fullyQualifiedEndpoint); - - return webTarget.request(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN); - } - - /** - * Assert that GET call to actuator endpoint is Unauthorized. - * - * @param endPoint the endpoint - * @throws Exception if an error occurs - */ - protected void assertUnauthorizedActGet(final String endPoint) throws Exception { - Response rawresp = sendNoAuthActRequest(endPoint).buildGet().invoke(); - assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus()); - } - - /** - * Set Up httpPrefix. - * - * @param port the port - */ - protected void setHttpPrefix(int port) { - httpPrefix = "http://" + SELF + ":" + port + "/"; - } - -} diff --git a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/utils/CommonTestData.java b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/utils/CommonTestData.java deleted file mode 100644 index 1f92a86e0..000000000 --- a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/utils/CommonTestData.java +++ /dev/null @@ -1,152 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.http.utils; - -import java.util.List; -import java.util.Map; -import java.util.UUID; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.participant.http.main.models.ConfigurationEntity; -import org.onap.policy.clamp.controlloop.participant.http.main.models.RestParams; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; - -public class CommonTestData { - - private static final String TEST_KEY_NAME = "org.onap.domain.database.Http_PMSHMicroserviceControlLoopElement"; - - - /** - * Get a controlLoop Element. - * @return controlLoopElement object - */ - public ControlLoopElement getControlLoopElement() { - ControlLoopElement element = new ControlLoopElement(); - element.setId(UUID.randomUUID()); - element.setDefinition(new ToscaConceptIdentifier(TEST_KEY_NAME, "1.0.1")); - element.setOrderedState(ControlLoopOrderedState.PASSIVE); - return element; - } - - /** - * Get query params. - * @return Map of query params - */ - public Map getQueryParams() { - return Map.of("name", "dummy", "version", "1.0"); - } - - /** - * Get path params. - * @return Map of path params - */ - public Map getPathParams() { - return Map.of("id", "123", "name", "dummy"); - } - - /** - * Rest params with GET request. - * @return RestParams obj - */ - public RestParams restParamsWithGet() { - return new RestParams( - new ToscaConceptIdentifier("getRequest", "1.0"), - "GET", - "get", - 200, - null, - getQueryParams(), - null - ); - } - - /** - * Rest params with POST request. - * @return RestParams obj - */ - public RestParams restParamsWithPost() { - return new RestParams( - new ToscaConceptIdentifier("postRequest", "1.0"), - "POST", - "post", - 200, - null, - getQueryParams(), - "Test body" - ); - } - - /** - * Rest params with POST request. - * @return RestParams obj - */ - public RestParams restParamsWithInvalidPost() { - return new RestParams( - new ToscaConceptIdentifier("postRequest", "1.0"), - "POST", - "post/{id}/{name}", - 200, - getPathParams(), - getQueryParams(), - "Test body" - ); - } - - /** - * Get invalid configuration entity. - * @return ConfigurationEntity obj - */ - public ConfigurationEntity getInvalidConfigurationEntity() { - return new ConfigurationEntity( - new ToscaConceptIdentifier("config1", "1.0.1"), - List.of(restParamsWithGet(), restParamsWithInvalidPost()) - ); - } - - /** - * Get configuration entity. - * @return ConfigurationEntity obj - */ - public ConfigurationEntity getConfigurationEntity() { - return new ConfigurationEntity( - new ToscaConceptIdentifier("config1", "1.0.1"), - List.of(restParamsWithGet(), restParamsWithPost()) - ); - } - - /** - * Get controlloop id. - * @return ToscaConceptIdentifier controlLoopId - */ - public ToscaConceptIdentifier getControlLoopId() { - return new ToscaConceptIdentifier("PMSHInstance0", "1.0.0"); - } - - /** - * Get headers for config request. - * @return Map of headers - */ - public Map getHeaders() { - return Map.of("Content-Type", "application/json", "Accept", "application/json"); - } - -} diff --git a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/utils/ToscaUtils.java b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/utils/ToscaUtils.java deleted file mode 100644 index fdba28c0e..000000000 --- a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/utils/ToscaUtils.java +++ /dev/null @@ -1,51 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.http.utils; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.onap.policy.common.utils.coder.YamlJsonTranslator; -import org.onap.policy.common.utils.resources.ResourceUtils; -import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; - -/** - * Util class for Test scope. - */ -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public final class ToscaUtils { - - private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator(); - private static final String TOSCA_TEMPLATE_YAML = "src/test/resources/HttpParticipantConfig.yaml"; - - - /** - * Read a service template yaml. - * @return ToscaServiceTemplate - */ - public static ToscaServiceTemplate readControlLoopFromTosca() { - return serializeControlLoopYaml(TOSCA_TEMPLATE_YAML); - } - - private static ToscaServiceTemplate serializeControlLoopYaml(String controlLoopFilePath) { - String controlLoopString = ResourceUtils.getResourceAsString(controlLoopFilePath); - return yamlTranslator.fromYaml(controlLoopString, ToscaServiceTemplate.class); - } -} diff --git a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/webclient/ClHttpClientTest.java b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/webclient/ClHttpClientTest.java deleted file mode 100644 index e3ff9dbba..000000000 --- a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/controlloop/participant/http/webclient/ClHttpClientTest.java +++ /dev/null @@ -1,129 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.http.webclient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.mockserver.model.HttpRequest.request; -import static org.mockserver.model.HttpResponse.response; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.ws.rs.core.MediaType; -import org.apache.commons.lang3.tuple.Pair; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockserver.integration.ClientAndServer; -import org.mockserver.model.Parameter; -import org.onap.policy.clamp.controlloop.participant.http.main.models.ConfigRequest; -import org.onap.policy.clamp.controlloop.participant.http.main.models.ConfigurationEntity; -import org.onap.policy.clamp.controlloop.participant.http.main.webclient.ClHttpClient; -import org.onap.policy.clamp.controlloop.participant.http.utils.CommonTestData; -import org.onap.policy.common.utils.network.NetworkUtil; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@ExtendWith(SpringExtension.class) -class ClHttpClientTest { - - private static CommonTestData commonTestData; - - private static int mockServerPort; - - private String testMockUrl = "http://localhost"; - - private Map> responseMap = new HashMap<>(); - - private static ClientAndServer mockServer; - - /** - * Set up Mock server. - */ - @BeforeAll - static void setUpMockServer() throws IOException { - mockServerPort = NetworkUtil.allocPort(); - mockServer = ClientAndServer.startClientAndServer(mockServerPort); - commonTestData = new CommonTestData(); - List queryParams = new ArrayList<>(); - commonTestData.getQueryParams().forEach((k, v) -> queryParams.add(new Parameter(k, v))); - - mockServer.when(request().withMethod("GET").withPath("/get") - .withHeader("Content-type", MediaType.APPLICATION_JSON) - .withHeader("Accept", MediaType.APPLICATION_JSON).withQueryStringParameters(queryParams)) - .respond(response().withBody("dummy body").withStatusCode(200) - .withHeader("Content-Type", MediaType.APPLICATION_JSON)); - - mockServer.when(request().withMethod("POST").withPath("/post") - .withHeader("Content-type", MediaType.APPLICATION_JSON) - .withHeader("Accept", MediaType.APPLICATION_JSON).withQueryStringParameters(queryParams) - .withBody("Test body")) - .respond(response().withStatusCode(200)); - } - - @AfterAll - public static void stopServer() { - mockServer.stop(); - mockServer = null; - } - - - @Test - void test_validRequest() { - //Add valid rest requests POST, GET - ConfigurationEntity configurationEntity = commonTestData.getConfigurationEntity(); - - Map headers = commonTestData.getHeaders(); - ConfigRequest configRequest = new ConfigRequest(testMockUrl + ":" + mockServerPort, headers, - List.of(configurationEntity), 10); - - ClHttpClient client = new ClHttpClient(configRequest, responseMap); - assertDoesNotThrow(client::run); - assertThat(responseMap).hasSize(2).containsKey(commonTestData - .restParamsWithGet().getRestRequestId()); - - Pair restResponseMap = responseMap.get(commonTestData - .restParamsWithGet().getRestRequestId()); - assertThat(restResponseMap.getKey()).isEqualTo(200); - } - - @Test - void test_invalidRequest() { - //Add rest requests Invalid POST, Valid GET - ConfigurationEntity configurationEntity = commonTestData.getInvalidConfigurationEntity(); - - Map headers = commonTestData.getHeaders(); - ConfigRequest configRequest = new ConfigRequest(testMockUrl + ":" + mockServerPort, headers, - List.of(configurationEntity), 10); - - ClHttpClient client = new ClHttpClient(configRequest, responseMap); - assertDoesNotThrow(client::run); - assertThat(responseMap).hasSize(2).containsKey(commonTestData - .restParamsWithGet().getRestRequestId()); - Pair response = responseMap - .get(commonTestData.restParamsWithInvalidPost().getRestRequestId()); - assertThat(response.getKey()).isEqualTo(404); - } -} diff --git a/participant/participant-impl/participant-impl-http/src/test/resources/HttpParticipantConfig.yaml b/participant/participant-impl/participant-impl-http/src/test/resources/HttpParticipantConfig.yaml index f221bcbd7..57c6e40d1 100644 --- a/participant/participant-impl/participant-impl-http/src/test/resources/HttpParticipantConfig.yaml +++ b/participant/participant-impl/participant-impl-http/src/test/resources/HttpParticipantConfig.yaml @@ -27,7 +27,7 @@ data_types: type: string required: true - org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.RestRequest: + org.onap.datatypes.policy.clamp.acm.httpAutomationCompositionElement.RestRequest: version: 1.0.0 derived_from: tosca.datatypes.Root properties: @@ -56,7 +56,7 @@ data_types: constraints: - in_range: [100, 599] description: THe expected HTTP status code for the REST request - org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.ConfigurationEntity: + org.onap.datatypes.policy.clamp.acm.httpAutomationCompositionElement.ConfigurationEntity: version: 1.0.0 derived_from: tosca.datatypes.Root properties: @@ -64,24 +64,24 @@ data_types: type: onap.datatypes.ToscaConceptIdentifier typeVersion: 1.0.0 required: true - description: The name and version of a Configuration Entity to be handled by the HTTP Control Loop Element + description: The name and version of a Configuration Entity to be handled by the HTTP Automation Composition Element restSequence: type: list entry_schema: - type: org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.RestRequest + type: org.onap.datatypes.policy.clamp.acm.httpAutomationCompositionElement.RestRequest typeVersion: 1.0.0 description: A sequence of REST commands to send to the REST endpoint node_types: - org.onap.policy.clamp.controlloop.Participant: + org.onap.policy.clamp.acm.Participant: version: 1.0.1 derived_from: tosca.nodetypes.Root properties: provider: type: string requred: false - org.onap.policy.clamp.controlloop.ControlLoopElement: + org.onap.policy.clamp.acm.AutomationCompositionElement: version: 1.0.1 derived_from: tosca.nodetypes.Root properties: @@ -98,11 +98,11 @@ node_types: - greater-or-equal: 0 metadata: common: true - description: A value indicating the start phase in which this control loop element will be started, the - first start phase is zero. Control Loop Elements are started in their start_phase order and stopped - in reverse start phase order. Control Loop Elements with the same start phase are started and + description: A value indicating the start phase in which this automation composition element will be started, the + first start phase is zero. Automation Composition Elements are started in their start_phase order and stopped + in reverse start phase order. Automation Composition Elements with the same start phase are started and stopped simultaneously - org.onap.policy.clamp.controlloop.ControlLoop: + org.onap.policy.clamp.acm.AutomationComposition: version: 1.0.1 derived_from: tosca.nodetypes.Root properties: @@ -114,9 +114,9 @@ node_types: required: true entry_schema: type: onap.datatypes.ToscaConceptIdentifier - org.onap.policy.clamp.controlloop.HttpControlLoopElement: + org.onap.policy.clamp.acm.HttpAutomationCompositionElement: version: 1.0.1 - derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement + derived_from: org.onap.policy.clamp.acm.AutomationCompositionElement properties: baseUrl: type: string @@ -132,29 +132,29 @@ node_types: type: map required: true entry_schema: - type: org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.ConfigurationEntity + type: org.onap.datatypes.policy.clamp.acm.httpAutomationCompositionElement.ConfigurationEntity typeVersion: 1.0.0 - description: The connfiguration entities the Control Loop Element is managing and their associated REST requests + description: The connfiguration entities the Automation Composition Element is managing and their associated REST requests topology_template: node_templates: - org.onap.k8s.controlloop.HttpControlLoopParticipant: + org.onap.k8s.acm.HttpAutomationCompositionParticipant: version: 2.3.4 - type: org.onap.policy.clamp.controlloop.Participant + type: org.onap.policy.clamp.acm.Participant type_version: 1.0.1 description: Participant for Http requests properties: provider: ONAP - org.onap.domain.database.Http_PMSHMicroserviceControlLoopElement: + org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement: # Http config for PMSH. version: 1.2.3 - type: org.onap.policy.clamp.controlloop.HttpControlLoopElement + type: org.onap.policy.clamp.acm.HttpAutomationCompositionElement type_version: 1.0.1 - description: Control loop element for the http requests of PMSH microservice + description: Automation composition element for the http requests of PMSH microservice properties: provider: ONAP participantType: - name: org.onap.controlloop.HttpControlLoopParticipant + name: org.onap.acm.HttpAutomationCompositionParticipant version: 2.3.4 startPhase: 1 uninitializedToPassiveTimeout: 180 @@ -208,13 +208,13 @@ topology_template: expectedResponse: 200 - org.onap.domain.sample.GenericK8s_ControlLoopDefinition: + org.onap.domain.sample.GenericK8s_AutomationCompositionDefinition: version: 1.2.3 - type: org.onap.policy.clamp.controlloop.ControlLoop + type: org.onap.policy.clamp.acm.AutomationComposition type_version: 1.0.0 - description: Control loop for HTTP request + description: Automation composition for HTTP request properties: provider: ONAP elements: - - name: org.onap.domain.database.Http_PMSHMicroserviceControlLoopElement + - name: org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement version: 1.2.3 diff --git a/participant/participant-impl/participant-impl-http/src/test/resources/application_test.properties b/participant/participant-impl/participant-impl-http/src/test/resources/application_test.properties index 698a965b8..e9f3b37cb 100644 --- a/participant/participant-impl/participant-impl-http/src/test/resources/application_test.properties +++ b/participant/participant-impl/participant-impl-http/src/test/resources/application_test.properties @@ -1,24 +1,24 @@ spring.security.user.name=participantUser spring.security.user.password=zb!XztG34 -server.servlet.context-path=/onap/httpparticipant +server.servlet.context-path=/onap/policy/clamp/acm/httpparticipant server.error.path=/error server.http-port=8084 -participant.name=ControlLoopParticipant Http Test +participant.name=AutomationCompositionParticipant Http Test participant.intermediaryParameters.name=Participant parameters participant.intermediaryParameters.reportingTimeInterval=120000 participant.intermediaryParameters.description=Participant Description participant.intermediaryParameters.participantId.name=HttpParticipant0 participant.intermediaryParameters.participantId.version=1.0.0 -participant.intermediaryParameters.participantType.name=org.onap.k8s.controlloop.HttpControlLoopParticipant +participant.intermediaryParameters.participantType.name=org.onap.clamp.acm.HttpParticipant participant.intermediaryParameters.participantType.version=2.3.4 -participant.intermediaryParameters.clampControlLoopTopics.name=ControlLoop Topics -participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].topic=POLICY-CLRUNTIME-PARTICIPANT -participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].servers[0]=localhost -participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].topicCommInfrastructure=dmaap -participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].fetchTimeout=15000 -participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].topic=POLICY-CLRUNTIME-PARTICIPANT -participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].servers[0]=localhost -participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].topicCommInfrastructure=dmaap +participant.intermediaryParameters.clampAutomationCompositionTopics.name=AutomationComposition Topics +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSources[0].topic=POLICY-ACRUNTIME-PARTICIPANT +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSources[0].servers[0]=localhost +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSources[0].topicCommInfrastructure=dmaap +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSources[0].fetchTimeout=15000 +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSinks[0].topic=POLICY-ACRUNTIME-PARTICIPANT +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSinks[0].servers[0]=localhost +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSinks[0].topicCommInfrastructure=dmaap management.endpoints.web.exposure.include=health,metrics,prometheus diff --git a/participant/participant-impl/participant-impl-kubernetes/pom.xml b/participant/participant-impl/participant-impl-kubernetes/pom.xml index 6bbf01757..e92021b92 100644 --- a/participant/participant-impl/participant-impl-kubernetes/pom.xml +++ b/participant/participant-impl/participant-impl-kubernetes/pom.xml @@ -30,7 +30,7 @@ policy-clamp-participant-impl-kubernetes ${project.artifactId} - Kubernetes participant, that allows k8s pods to partake in control loops + Kubernetes participant, that allows k8s pods to partake in automation compositions diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/Application.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/Application.java new file mode 100644 index 000000000..6908b2760 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/Application.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.kubernetes; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.ConfigurationPropertiesScan; +import org.springframework.context.annotation.ComponentScan; + +/** + * Starter. + * + */ +// @formatter:off +@SpringBootApplication +@ComponentScan({ + "org.onap.policy.clamp.acm.participant.kubernetes", + "org.onap.policy.clamp.acm.participant.intermediary" +}) +@ConfigurationPropertiesScan("org.onap.policy.clamp.acm.participant.kubernetes.parameters") +//@formatter:on +public class Application { + /** + * Main class. + * + * @param args args + */ + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/ParticipantConfig.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/ParticipantConfig.java new file mode 100644 index 000000000..428819be9 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/ParticipantConfig.java @@ -0,0 +1,44 @@ +/*- + * ========================LICENSE_START================================= + * Copyright (C) 2021 Nordix Foundation. All rights reserved. + * ====================================================================== + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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.onap.policy.clamp.acm.participant.kubernetes.configurations; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.multipart.MultipartResolver; +import org.springframework.web.multipart.commons.CommonsMultipartResolver; + +/** + * Bean Factory class for helm client. + */ +@Configuration +public class ParticipantConfig { + + /** + * Method to create multipartResolver bean. + * @return MultipartResolver + */ + @Bean(name = "multipartResolver") + public MultipartResolver multipartResolver() { + var multipartResolver = new CommonsMultipartResolver(); + multipartResolver.setMaxUploadSize(100000); + return multipartResolver; + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/ParticipantIntermediaryConfig.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/ParticipantIntermediaryConfig.java new file mode 100644 index 000000000..878b43f48 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/ParticipantIntermediaryConfig.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.kubernetes.configurations; + +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.acm.participant.kubernetes.handler.AutomationCompositionElementHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ParticipantIntermediaryConfig { + + /** + * Register AutomationCompositionElementListener. + * + * @param intermediaryApi the ParticipantIntermediaryApi + * @param acElementHandler the AutomationComposition Element Handler + */ + @Autowired + public void registerAutomationCompositionElementListener(ParticipantIntermediaryApi intermediaryApi, + AutomationCompositionElementHandler acElementHandler) { + intermediaryApi.registerAutomationCompositionElementListener(acElementHandler); + acElementHandler.setIntermediaryApi(intermediaryApi); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/SecurityConfig.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/SecurityConfig.java new file mode 100644 index 000000000..da5762b43 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/SecurityConfig.java @@ -0,0 +1,45 @@ +/*- + * ========================LICENSE_START================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.kubernetes.configurations; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Value("${security.enable-csrf:true}") + private boolean csrfEnabled = true; + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.authorizeRequests() + .antMatchers().authenticated() + .anyRequest().authenticated() + .and().httpBasic(); + // @formatter:on + + if (!csrfEnabled) { + http.csrf().disable(); + } + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/SpringFoxConfig.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/SpringFoxConfig.java new file mode 100644 index 000000000..cfa98bd65 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/configurations/SpringFoxConfig.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.kubernetes.configurations; + +import org.onap.policy.clamp.acm.participant.kubernetes.controller.ChartController; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; + +@Configuration +public class SpringFoxConfig { + + /** + * Docket Spring Fox Config. + * + * @return Docket + */ + @Bean + public Docket api() { + return new Docket(DocumentationType.SWAGGER_2).select() + .apis(RequestHandlerSelectors.basePackage(ChartController.class.getPackageName())) + .paths(PathSelectors.any()).build(); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/controller/ChartController.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/controller/ChartController.java new file mode 100644 index 000000000..19ab4bbab --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/controller/ChartController.java @@ -0,0 +1,195 @@ +/*- + * ========================LICENSE_START================================= + * Copyright (C) 2021-2022 Nordix Foundation. All rights reserved. + * ====================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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.onap.policy.clamp.acm.participant.kubernetes.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import java.io.IOException; +import java.util.ArrayList; +import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartList; +import org.onap.policy.clamp.acm.participant.kubernetes.models.HelmRepository; +import org.onap.policy.clamp.acm.participant.kubernetes.models.InstallationInfo; +import org.onap.policy.clamp.acm.participant.kubernetes.service.ChartService; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +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.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +@RestController("chartController") +@ConditionalOnExpression("${chart.api.enabled:false}") +@RequestMapping("helm") +@Api(tags = {"k8s-participant"}) +public class ChartController { + + @Autowired + private ChartService chartService; + + private static final StandardCoder CODER = new StandardCoder(); + + /** + * REST endpoint to get all the charts. + * + * @return List of charts installed + */ + @GetMapping(path = "/charts", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(value = "Return all Charts") + @ApiResponses(value = {@ApiResponse(code = 200, message = "chart List")}) + public ResponseEntity getAllCharts() { + return new ResponseEntity<>(ChartList.builder().charts(new ArrayList<>(chartService.getAllCharts())).build(), + HttpStatus.OK); + } + + /** + * REST endpoint to install a helm chart. + * + * @param info Info of the chart to be installed + * @return Status of the install operation + * @throws ServiceException in case of error + * @throws IOException in case of IO error + */ + @PostMapping(path = "/install", consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(value = "Install the chart") + @ApiResponses(value = {@ApiResponse(code = 201, message = "chart Installed")}) + public ResponseEntity installChart(@RequestBody InstallationInfo info) + throws ServiceException, IOException { + ChartInfo chart = chartService.getChart(info.getName(), info.getVersion()); + if (chart == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + chartService.installChart(chart); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + /** + * REST endpoint to uninstall a specific chart. + * + * @param name name of the chart + * @param version version of the chart + * @return Status of operation + * @throws ServiceException in case of error. + */ + @DeleteMapping(path = "/uninstall/{name}/{version}", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(value = "Uninstall the Chart") + @ApiResponses(value = {@ApiResponse(code = 201, message = "chart Uninstalled")}) + public ResponseEntity uninstallChart(@PathVariable("name") String name, + @PathVariable("version") String version) throws ServiceException { + ChartInfo chart = chartService.getChart(name, version); + if (chart == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + chartService.uninstallChart(chart); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + /** + * REST endpoint to onboard a chart. + * + * @param chartFile Multipart file for the helm chart + * @param infoJson AppInfo of the chart + * @param overrideFile the file for overriding the chart + * @return Status of onboard operation + * @throws ServiceException in case of error + * @throws IOException in case of IO error + */ + @PostMapping(path = "/onboard/chart", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(value = "Onboard the Chart") + @ApiResponses(value = {@ApiResponse(code = 201, message = "Chart Onboarded")}) + public ResponseEntity onboardChart(@RequestPart("chart") MultipartFile chartFile, + @RequestParam(name = "values", required = false) MultipartFile overrideFile, + @RequestParam("info") String infoJson) throws ServiceException, IOException { + + ChartInfo info; + try { + info = CODER.decode(infoJson, ChartInfo.class); + } catch (CoderException e) { + throw new ServiceException("Error parsing the chart information", e); + } + + chartService.saveChart(info, chartFile, overrideFile); + return new ResponseEntity<>(HttpStatus.OK); + } + + /** + * REST endpoint to delete a specific helm chart. + * + * @param name name of the chart + * @param version version of the chart + * @return Status of operation + */ + @DeleteMapping(path = "/chart/{name}/{version}") + @ApiOperation(value = "Delete the chart") + @ApiResponses(value = {@ApiResponse(code = 204, message = "Chart Deleted")}) + public ResponseEntity deleteChart(@PathVariable("name") String name, + @PathVariable("version") String version) { + + ChartInfo chart = chartService.getChart(name, version); + if (chart == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + chartService.deleteChart(chart); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + /** + * REST endpoint to configure a helm Repository. + * + * @param repo Helm repository to be configured + * @return Status of the operation + * @throws ServiceException in case of error + * @throws IOException in case of IO error + */ + @PostMapping(path = "/repo", consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(value = "Configure helm repository") + @ApiResponses(value = {@ApiResponse(code = 201, message = "Repository added")}) + public ResponseEntity configureRepo(@RequestBody String repo) + throws ServiceException, IOException { + HelmRepository repository; + try { + repository = CODER.decode(repo, HelmRepository.class); + } catch (CoderException e) { + throw new ServiceException("Error parsing the repository information", e); + } + chartService.configureRepository(repository); + + return new ResponseEntity<>(HttpStatus.CREATED); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/exception/ServiceException.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/exception/ServiceException.java new file mode 100644 index 000000000..6414f2fa9 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/exception/ServiceException.java @@ -0,0 +1,32 @@ +/*- + * ========================LICENSE_START================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.kubernetes.exception; + +public class ServiceException extends Exception { + + private static final long serialVersionUID = 6810785674716590648L; + + public ServiceException(String message) { + super(message); + } + + public ServiceException(String message, Exception originalException) { + super(message, originalException); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandler.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandler.java new file mode 100644 index 000000000..753608686 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandler.java @@ -0,0 +1,197 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021-2022 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.onap.policy.clamp.acm.participant.kubernetes.handler; + +import java.io.IOException; +import java.lang.invoke.MethodHandles; +import java.time.Instant; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; +import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener; +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.acm.participant.kubernetes.helm.PodStatusValidator; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.acm.participant.kubernetes.service.ChartService; +import org.onap.policy.clamp.models.acm.concepts.AcElementStatistics; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * This class handles implementation of automationCompositionElement updates. + */ +@Component +public class AutomationCompositionElementHandler implements AutomationCompositionElementListener { + private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + private ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + + // Map of helm installation and the status of corresponding pods + @Getter + private static Map> podStatusMap = new ConcurrentHashMap<>(); + private static final Coder CODER = new StandardCoder(); + + @Autowired + private ChartService chartService; + + @Setter + private ParticipantIntermediaryApi intermediaryApi; + + // Map of acElement Id and installed Helm charts + @Getter(AccessLevel.PACKAGE) + private final Map chartMap = new HashMap<>(); + + // Default thread config values + private static class ThreadConfig { + private int uninitializedToPassiveTimeout = 60; + private int podStatusCheckInterval = 30; + } + + /** + * Callback method to handle a automation composition element state change. + * + * @param automationCompositionElementId the ID of the automation composition element + * @param currentState the current state of the automation composition element + * @param newState the state to which the automation composition element is changing to + */ + @Override + public synchronized void automationCompositionElementStateChange(ToscaConceptIdentifier automationCompositionId, + UUID automationCompositionElementId, AutomationCompositionState currentState, + AutomationCompositionOrderedState newState) { + switch (newState) { + case UNINITIALISED: + ChartInfo chart = chartMap.get(automationCompositionElementId); + if (chart != null) { + LOGGER.info("Helm deployment to be deleted {} ", chart.getReleaseName()); + try { + chartService.uninstallChart(chart); + intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, + automationCompositionElementId, newState, AutomationCompositionState.UNINITIALISED, + ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE); + chartMap.remove(automationCompositionElementId); + podStatusMap.remove(chart.getReleaseName()); + } catch (ServiceException se) { + LOGGER.warn("Deletion of Helm deployment failed", se); + } + } + break; + case PASSIVE: + intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, + automationCompositionElementId, newState, AutomationCompositionState.PASSIVE, + ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE); + break; + case RUNNING: + intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, + automationCompositionElementId, newState, AutomationCompositionState.RUNNING, + ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE); + break; + default: + LOGGER.warn("Cannot transition from state {} to state {}", currentState, newState); + break; + } + } + + /** + * Callback method to handle an update on a automation composition element. + * + * @param element the information on the automation composition element + * @param nodeTemplate toscaNodeTemplate + * @throws PfModelException in case of an exception + */ + @Override + public synchronized void automationCompositionElementUpdate(ToscaConceptIdentifier automationCompositionId, + AutomationCompositionElement element, ToscaNodeTemplate nodeTemplate) throws PfModelException { + @SuppressWarnings("unchecked") + Map chartData = (Map) nodeTemplate.getProperties().get("chart"); + + LOGGER.info("Installation request received for the Helm Chart {} ", chartData); + try { + var chartInfo = CODER.convert(chartData, ChartInfo.class); + chartService.installChart(chartInfo); + chartMap.put(element.getId(), chartInfo); + + var config = CODER.convert(nodeTemplate.getProperties(), ThreadConfig.class); + checkPodStatus(automationCompositionId, element.getId(), chartInfo, config.uninitializedToPassiveTimeout, + config.podStatusCheckInterval); + + } catch (ServiceException | CoderException | IOException | ExecutionException + | InterruptedException e) { + LOGGER.warn("Installation of Helm chart failed", e); + } + } + + /** + * Invoke a new thread to check the status of deployed pods. + * + * @param chart ChartInfo + */ + public void checkPodStatus(ToscaConceptIdentifier controlLoopId, UUID elementId, + ChartInfo chart, int timeout, int podStatusCheckInterval) throws ExecutionException, InterruptedException { + // Invoke runnable thread to check pod status + Future result = executor.submit(new PodStatusValidator(chart, timeout, + podStatusCheckInterval), "Done"); + if (!result.get().isEmpty()) { + LOGGER.info("Pod Status Validator Completed: {}", result.isDone()); + intermediaryApi.updateAutomationCompositionElementState(controlLoopId, elementId, + AutomationCompositionOrderedState.PASSIVE, AutomationCompositionState.PASSIVE, + ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE); + } + } + + /** + * Overridden method. + * + * @param automationCompositionElementId automationCompositionElement id + * @throws PfModelException in case of error + */ + @Override + public synchronized void handleStatistics(UUID automationCompositionElementId) throws PfModelException { + var acElement = intermediaryApi.getAutomationCompositionElement(automationCompositionElementId); + if (acElement != null) { + var acElementStatistics = new AcElementStatistics(); + acElementStatistics.setState(acElement.getState()); + acElementStatistics.setTimeStamp(Instant.now()); + intermediaryApi.updateAutomationCompositionElementStatistics(automationCompositionElementId, + acElementStatistics); + } + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/HelmClient.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/HelmClient.java new file mode 100644 index 000000000..87199688e --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/HelmClient.java @@ -0,0 +1,279 @@ +/*- + * ========================LICENSE_START================================= + * Copyright (C) 2021-2022 Nordix Foundation. All rights reserved. + * ====================================================================== + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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.onap.policy.clamp.acm.participant.kubernetes.helm; + +import java.io.File; +import java.io.IOException; +import java.lang.invoke.MethodHandles; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import org.apache.commons.io.IOUtils; +import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.acm.participant.kubernetes.models.HelmRepository; +import org.onap.policy.clamp.acm.participant.kubernetes.service.ChartStore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Client to talk with Helm cli. Supports helm3 + version + */ +@Component +public class HelmClient { + + @Autowired + private ChartStore chartStore; + + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + private static final String PATH_DELIMITER = "/"; + + /** + * Install a chart. + * + * @param chart name and version. + * @throws ServiceException incase of error + */ + public void installChart(ChartInfo chart) throws ServiceException { + if (! checkNamespaceExists(chart.getNamespace())) { + var processBuilder = prepareCreateNamespaceCommand(chart.getNamespace()); + executeCommand(processBuilder); + } + var processBuilder = prepareInstallCommand(chart); + logger.info("Installing helm chart {} from the repository {} ", chart.getChartId().getName(), + chart.getRepository().getRepoName()); + executeCommand(processBuilder); + logger.info("Chart {} installed successfully", chart.getChartId().getName()); + } + + /** + * Add repository if doesn't exist. + * @param repo HelmRepository + * @throws ServiceException incase of error + */ + public void addRepository(HelmRepository repo) throws ServiceException { + String output = executeCommand(prepareVerifyRepoCommand(repo)); + if (output.isEmpty()) { + logger.info("Adding repository to helm client"); + executeCommand(prepareRepoAddCommand(repo)); + logger.debug("Added repository {} to the helm client", repo.getRepoName()); + } else { + logger.info("Repository already exists"); + } + } + + + /** + * Finds helm chart repository for the chart. + * + * @param chart ChartInfo. + * @return the chart repository as a string + * @throws ServiceException in case of error + * @throws IOException in case of IO errors + */ + public String findChartRepository(ChartInfo chart) throws ServiceException, IOException { + if (updateHelmRepo()) { + String repository = verifyConfiguredRepo(chart); + if (repository != null) { + logger.info("Helm chart located in the repository {} ", repository); + return repository; + } + } + var localHelmChartDir = chartStore.getAppPath(chart.getChartId()).toString(); + logger.info("Chart not found in helm repositories, verifying local repo {} ", localHelmChartDir); + if (verifyLocalHelmRepo(new File(localHelmChartDir + PATH_DELIMITER + chart.getChartId().getName()))) { + return localHelmChartDir; + } + return null; + } + + /** + * Verify helm chart in configured repositories. + * @param chart chartInfo + * @return repo name + * @throws IOException incase of error + * @throws ServiceException incase of error + */ + public String verifyConfiguredRepo(ChartInfo chart) throws IOException, ServiceException { + logger.info("Looking for helm chart {} in all the configured helm repositories", chart.getChartId().getName()); + String repository = null; + var builder = helmRepoVerifyCommand(chart.getChartId().getName()); + String output = executeCommand(builder); + repository = verifyOutput(output, chart.getChartId().getName()); + return repository; + } + + /** + * Uninstall a chart. + * + * @param chart name and version. + * @throws ServiceException incase of error + */ + public void uninstallChart(ChartInfo chart) throws ServiceException { + executeCommand(prepareUnInstallCommand(chart)); + } + + + /** + * Execute helm cli bash commands . + * @param processBuilder processbuilder + * @return string output + * @throws ServiceException incase of error. + */ + public static String executeCommand(ProcessBuilder processBuilder) throws ServiceException { + var commandStr = toString(processBuilder); + + try { + var process = processBuilder.start(); + process.waitFor(); + int exitValue = process.exitValue(); + + if (exitValue != 0) { + var error = IOUtils.toString(process.getErrorStream(), StandardCharsets.UTF_8); + if (! error.isEmpty()) { + throw new ServiceException("Command execution failed: " + commandStr + " " + error); + } + } + + var output = IOUtils.toString(process.getInputStream(), StandardCharsets.UTF_8); + logger.debug("Command <{}> execution, output: {}", commandStr, output); + return output; + + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + throw new ServiceException("Failed to execute the Command: " + commandStr + ", the command was interrupted", + ie); + } catch (Exception exc) { + throw new ServiceException("Failed to execute the Command: " + commandStr, exc); + } + } + + private boolean checkNamespaceExists(String namespace) throws ServiceException { + logger.info("Check if namespace {} exists on the cluster", namespace); + String output = executeCommand(prepareVerifyNamespaceCommand(namespace)); + return !output.isEmpty(); + } + + private String verifyOutput(String output, String value) { + for (var line: output.split("\\R")) { + if (line.contains(value)) { + return line.split("/")[0]; + } + } + return null; + } + + private ProcessBuilder prepareRepoAddCommand(HelmRepository repo) { + var url = repo.getProtocol() + "://" + repo.getAddress(); + if (repo.getPort() != null) { + url = url + ":" + repo.getPort(); + } + // @formatter:off + List helmArguments = new ArrayList<>( + List.of( + "helm", + "repo", + "add", repo.getRepoName(), url + )); + if (repo.getUserName() != null && repo.getPassword() != null) { + helmArguments.addAll(List.of("--username", repo.getUserName(), "--password", repo.getPassword())); + } + return new ProcessBuilder().command(helmArguments); + } + + private ProcessBuilder prepareVerifyRepoCommand(HelmRepository repo) { + List helmArguments = List.of("sh", "-c", "helm repo ls | grep " + repo.getRepoName()); + return new ProcessBuilder().command(helmArguments); + } + + private ProcessBuilder prepareVerifyNamespaceCommand(String namespace) { + List helmArguments = List.of("sh", "-c", "kubectl get ns | grep " + namespace); + return new ProcessBuilder().command(helmArguments); + } + + private ProcessBuilder prepareInstallCommand(ChartInfo chart) { + + // @formatter:off + List helmArguments = new ArrayList<>( + List.of( + "helm", + "install", chart.getReleaseName(), chart.getRepository().getRepoName() + "/" + + chart.getChartId().getName(), + "--version", chart.getChartId().getVersion(), + "--namespace", chart.getNamespace() + )); + // @formatter:on + + // Verify if values.yaml/override parameters available for the chart + var localOverrideYaml = chartStore.getOverrideFile(chart); + + if (verifyLocalHelmRepo(localOverrideYaml)) { + logger.info("Override yaml available for the helm chart"); + helmArguments.addAll(List.of("--values", localOverrideYaml.getPath())); + } + + if (chart.getOverrideParams() != null) { + for (Map.Entry entry : chart.getOverrideParams().entrySet()) { + helmArguments.addAll(List.of("--set", entry.getKey() + "=" + entry.getValue())); + } + } + return new ProcessBuilder().command(helmArguments); + } + + private ProcessBuilder prepareUnInstallCommand(ChartInfo chart) { + return new ProcessBuilder("helm", "delete", chart.getReleaseName(), "--namespace", + chart.getNamespace()); + } + + private ProcessBuilder prepareCreateNamespaceCommand(String namespace) { + return new ProcessBuilder().command("kubectl", "create", "namespace", namespace); + } + + private ProcessBuilder helmRepoVerifyCommand(String chartName) { + return new ProcessBuilder().command("sh", "-c", "helm search repo | grep " + chartName); + } + + + private boolean updateHelmRepo() { + try { + logger.info("Updating local helm repositories before verifying the chart"); + executeCommand(new ProcessBuilder().command("helm", "repo", "update")); + logger.debug("Helm repositories updated successfully"); + } catch (ServiceException e) { + logger.error("Failed to update the helm repo: ", e); + return false; + } + return true; + + + } + + private boolean verifyLocalHelmRepo(File localFile) { + return localFile.exists(); + } + + protected static String toString(ProcessBuilder processBuilder) { + return String.join(" ", processBuilder.command()); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidator.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidator.java new file mode 100644 index 000000000..f8b08a6be --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidator.java @@ -0,0 +1,119 @@ +/*- + * ========================LICENSE_START================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.kubernetes.helm; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.invoke.MethodHandles; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import lombok.SneakyThrows; +import org.apache.commons.io.IOUtils; +import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.acm.participant.kubernetes.handler.AutomationCompositionElementHandler; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class PodStatusValidator implements Runnable { + + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + private final int statusCheckInterval; + + //Timeout for the thread to exit. + private final int timeout; + + private ChartInfo chart; + + /** + * Constructor for PodStatusValidator. + * @param chart chartInfo + * @param timeout timeout for the thread to exit + * @param statusCheckInterval Interval to check pod status + */ + public PodStatusValidator(ChartInfo chart, int timeout, int statusCheckInterval) { + this.chart = chart; + this.timeout = timeout; + this.statusCheckInterval = statusCheckInterval; + } + + + @SneakyThrows + @Override + public void run() { + logger.info("Polling the status of deployed pods for the chart {}", chart.getChartId().getName()); + Map podStatusMap; + String output = null; + var isVerified = false; + long endTime = System.currentTimeMillis() + (timeout * 1000L); + + while (!isVerified && System.currentTimeMillis() < endTime) { + try { + output = HelmClient.executeCommand(verifyPodStatusCommand(chart)); + podStatusMap = mapPodStatus(output); + isVerified = podStatusMap.values() + .stream() + .allMatch("Running"::equals); + if (! isVerified) { + logger.info("Waiting for the pods to be active for the chart {}", chart.getChartId().getName()); + podStatusMap.forEach((key, value) -> logger.info("Pod: {} , state: {}", key, value)); + AutomationCompositionElementHandler.getPodStatusMap().put(chart.getReleaseName(), podStatusMap); + // Recheck status of pods in specific intervals. + Thread.sleep(statusCheckInterval * 1000L); + } else { + logger.info("All pods are in running state for the helm chart {}", chart.getChartId().getName()); + AutomationCompositionElementHandler.getPodStatusMap().put(chart.getReleaseName(), podStatusMap); + } + } catch (ServiceException | IOException e) { + throw new ServiceException("Error verifying the status of the pod. Exiting", e); + } + } + } + + private ProcessBuilder verifyPodStatusCommand(ChartInfo chart) { + String podName = chart.getReleaseName() + "-" + chart.getChartId().getName(); + String cmd = "kubectl get pods --namespace " + chart.getNamespace() + " | grep " + podName; + return new ProcessBuilder("sh", "-c", cmd); + } + + + private Map mapPodStatus(String output) throws IOException, ServiceException { + Map podStatusMap = new HashMap<>(); + try (var reader = new BufferedReader(new InputStreamReader(IOUtils.toInputStream(output, + StandardCharsets.UTF_8)))) { + var line = reader.readLine(); + while (line != null) { + if (line.contains(chart.getChartId().getName())) { + var result = line.split("\\s+"); + podStatusMap.put(result[0], result[2]); + } + line = reader.readLine(); + } + } + if (!podStatusMap.isEmpty()) { + return podStatusMap; + } else { + throw new ServiceException("Status of Pod is empty"); + } + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/models/ChartInfo.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/models/ChartInfo.java new file mode 100644 index 000000000..b925e782d --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/models/ChartInfo.java @@ -0,0 +1,44 @@ +/*- + * ========================LICENSE_START================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.kubernetes.models; + +import java.util.Map; +import lombok.Data; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +@Data +@RequiredArgsConstructor +public class ChartInfo { + + @NonNull + private String releaseName; + + @NonNull + private ToscaConceptIdentifier chartId; + + @NonNull + private String namespace; + + private HelmRepository repository; + + private Map overrideParams; + +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/models/ChartList.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/models/ChartList.java new file mode 100644 index 000000000..951bdaa1b --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/models/ChartList.java @@ -0,0 +1,31 @@ +/*- + * ========================LICENSE_START================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.kubernetes.models; + +import java.util.List; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Builder +public class ChartList { + private List charts; +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/models/HelmRepository.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/models/HelmRepository.java new file mode 100644 index 000000000..2e25e42a6 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/models/HelmRepository.java @@ -0,0 +1,39 @@ +/*- + * ========================LICENSE_START================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.kubernetes.models; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class HelmRepository { + + private String repoName; + + private String protocol; + + private String address; + + private String port; + + private String userName; + + private String password; +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/models/InstallationInfo.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/models/InstallationInfo.java new file mode 100644 index 000000000..6ef6865cb --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/models/InstallationInfo.java @@ -0,0 +1,29 @@ +/*- + * ========================LICENSE_START================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.kubernetes.models; + +import lombok.Getter; +import org.immutables.gson.Gson; + +@Getter +@Gson.TypeAdapters +public class InstallationInfo { + private String name; + private String version; +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/ParticipantK8sParameters.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/ParticipantK8sParameters.java new file mode 100644 index 000000000..b95756ec5 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/ParticipantK8sParameters.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.kubernetes.parameters; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; +import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantIntermediaryParameters; +import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantParameters; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.validation.annotation.Validated; + +/** + * Class to hold all parameters needed for the kubernetes participant. + * + */ +@Validated +@Getter +@Setter +@ConfigurationProperties(prefix = "participant") +public class ParticipantK8sParameters implements ParticipantParameters { + + @NotNull + @Valid + private ParticipantIntermediaryParameters intermediaryParameters; + + @NotBlank + private String localChartDirectory; + + @NotBlank + private String infoFileName; +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartService.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartService.java new file mode 100644 index 000000000..344d161b7 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartService.java @@ -0,0 +1,141 @@ +/*- + * ========================LICENSE_START================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.kubernetes.service; + +import java.io.IOException; +import java.lang.invoke.MethodHandles; +import java.util.Collection; +import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.acm.participant.kubernetes.helm.HelmClient; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.acm.participant.kubernetes.models.HelmRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +@Service +public class ChartService { + private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + @Autowired + private ChartStore chartStore; + + @Autowired + private HelmClient helmClient; + + /** + * Get all the installed charts. + * @return list of charts. + */ + public Collection getAllCharts() { + return chartStore.getAllCharts(); + } + + /** + * Get specific chart info. + * @param name name of the app + * @param version version of the app + * @return chart + */ + public ChartInfo getChart(String name, String version) { + return chartStore.getChart(name, version); + } + + /** + * Save a helm chart. + * @param chartInfo name and version of the app. + * @param chartFile Helm chart file + * @param overrideFile override file + * @return chart details of the helm chart + * @throws IOException in case of IO error + * @throws ServiceException in case of error + */ + public ChartInfo saveChart(ChartInfo chartInfo, MultipartFile chartFile, MultipartFile overrideFile) + throws IOException, ServiceException { + return chartStore.saveChart(chartInfo, chartFile, overrideFile); + } + + /** + * Delete a helm chart. + * @param chart name and version of the chart. + */ + public void deleteChart(ChartInfo chart) { + chartStore.deleteChart(chart); + } + + /** + * Install a helm chart. + * @param chart name and version. + * @throws ServiceException in case of error + * @throws IOException in case of IO errors + */ + public void installChart(ChartInfo chart) throws ServiceException, IOException { + if (chart.getRepository() == null) { + String repoName = findChartRepo(chart); + if (repoName == null) { + logger.error("Chart repository could not be found. Skipping chart Installation " + + "for the chart {} ", chart.getChartId().getName()); + return; + } else { + HelmRepository repo = HelmRepository.builder().repoName(repoName).build(); + chart.setRepository(repo); + } + } else { + // Add remote repository if passed via TOSCA + configureRepository(chart.getRepository()); + } + helmClient.installChart(chart); + } + + + /** + * Configure remote repository. + * @param repo HelmRepository + * @throws ServiceException incase of error + */ + public void configureRepository(HelmRepository repo) throws ServiceException { + if (repo.getAddress() != null) { + helmClient.addRepository(repo); + } + } + + /** + * Finds helm chart repository for a given chart. + * @param chart chartInfo. + * @return the chart repo as a string + * @throws ServiceException in case of error + * @throws IOException in case of IO errors + */ + public String findChartRepo(ChartInfo chart) throws ServiceException, IOException { + logger.info("Fetching helm chart repository for the given chart {} ", chart.getChartId().getName()); + return helmClient.findChartRepository(chart); + } + + /** + * Uninstall a helm chart. + * @param chart name and version + * @throws ServiceException in case of error. + */ + public void uninstallChart(ChartInfo chart) throws ServiceException { + logger.info("Uninstalling helm deployment {}", chart.getReleaseName()); + helmClient.uninstallChart(chart); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartStore.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartStore.java new file mode 100644 index 000000000..52c1b1f04 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartStore.java @@ -0,0 +1,219 @@ +/*- + * ========================LICENSE_START================================= + * Copyright (C) 2021 Nordix Foundation. All rights reserved. + * ====================================================================== + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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.onap.policy.clamp.acm.participant.kubernetes.service; + +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.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import lombok.AccessLevel; +import lombok.Getter; +import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.acm.participant.kubernetes.parameters.ParticipantK8sParameters; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.util.FileSystemUtils; +import org.springframework.web.multipart.MultipartFile; + +@Component +public class ChartStore { + private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + private static final StandardCoder STANDARD_CODER = new StandardCoder(); + + private final ParticipantK8sParameters participantK8sParameters; + + // ChartStore map contains chart name as key & ChartInfo as value. + @Getter(AccessLevel.PACKAGE) + private Map localChartMap = new ConcurrentHashMap<>(); + + /** + * Constructor method. + */ + public ChartStore(ParticipantK8sParameters participantK8sParameters) { + this.participantK8sParameters = participantK8sParameters; + this.restoreFromLocalFileSystem(); + } + + /** + * Get local helm chart file. + * + * @param chart ChartInfo + * @return the chart file. + */ + public File getHelmChartFile(ChartInfo chart) { + var appPath = getAppPath(chart.getChartId()); + return new File(appPath.toFile(), chart.getChartId().getName()); + } + + /** + * Get the override yaml file. + * + * @param chart ChartInfo + * @return the override yaml file + */ + public File getOverrideFile(ChartInfo chart) { + var appPath = getAppPath(chart.getChartId()); + return new File(appPath.toFile(), "values.yaml"); + } + + + /** + * Saves the helm chart. + * + * @param chartInfo chartInfo + * @param chartFile helm chart file. + * @param overrideFile override file. + * @return chart + * @throws IOException incase of IO error + * @throws ServiceException incase of error. + */ + public synchronized ChartInfo saveChart(ChartInfo chartInfo, MultipartFile chartFile, MultipartFile overrideFile) + throws IOException, ServiceException { + if (localChartMap.containsKey(key(chartInfo))) { + throw new ServiceException("Chart already exist"); + } + var appPath = getAppPath(chartInfo.getChartId()); + Files.createDirectories(appPath); + + chartFile.transferTo(getHelmChartFile(chartInfo)); + if (overrideFile != null) { + overrideFile.transferTo(getOverrideFile(chartInfo)); + } + + localChartMap.put(key(chartInfo), chartInfo); + storeChartInFile(chartInfo); + return chartInfo; + } + + /** + * Get the chart info. + * + * @param name name of the chart + * @param version version of the chart + * @return chart + */ + public synchronized ChartInfo getChart(String name, String version) { + return localChartMap.get(key(name, version)); + } + + /** + * Get all the charts installed. + * + * @return list of charts. + */ + public synchronized List getAllCharts() { + return new ArrayList<>(localChartMap.values()); + } + + /** + * Delete a chart. + * + * @param chart chart info + */ + public synchronized void deleteChart(ChartInfo chart) { + var appPath = getAppPath(chart.getChartId()); + try { + FileSystemUtils.deleteRecursively(appPath); + } catch (IOException exc) { + LOGGER.warn("Could not delete chart from local file system : {}", appPath, exc); + } + + localChartMap.remove(key(chart)); + } + + /** + * Fetch the local chart directory of specific chart. + * + * @param chartId Id of the chart + * @return path + */ + public Path getAppPath(ToscaConceptIdentifier chartId) { + return Path.of(participantK8sParameters.getLocalChartDirectory(), chartId.getName(), chartId.getVersion()); + } + + private void storeChartInFile(ChartInfo chart) { + try (var out = new PrintStream(new FileOutputStream(getFile(chart)))) { + out.print(STANDARD_CODER.encode(chart)); + } catch (Exception exc) { + LOGGER.warn("Could not store chart: {}", chart.getChartId(), exc); + } + } + + private File getFile(ChartInfo chart) { + var appPath = getAppPath(chart.getChartId()).toString(); + return Path.of(appPath, participantK8sParameters.getInfoFileName()).toFile(); + } + + private synchronized void restoreFromLocalFileSystem() { + try { + var localChartDirectoryPath = Paths.get(participantK8sParameters.getLocalChartDirectory()); + Files.createDirectories(localChartDirectoryPath); + restoreFromLocalFileSystem(localChartDirectoryPath); + } catch (Exception ioe) { + LOGGER.warn("Could not restore charts from local file system", ioe); + } + } + + private synchronized void restoreFromLocalFileSystem(Path localChartDirectoryPath) + throws IOException { + + Files.walkFileTree(localChartDirectoryPath, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path localChartFile, BasicFileAttributes attrs) throws IOException { + try { + // Decode only the json file excluding the helm charts + if (localChartFile.endsWith(participantK8sParameters.getInfoFileName())) { + ChartInfo chart = STANDARD_CODER.decode(localChartFile.toFile(), ChartInfo.class); + localChartMap.put(key(chart), chart); + } + return FileVisitResult.CONTINUE; + } catch (CoderException ce) { + throw new IOException("Error decoding chart file", ce); + } + } + }); + } + + private String key(ChartInfo chart) { + return key(chart.getChartId().getName(), chart.getChartId().getVersion()); + } + + private String key(String chartName, String chartVersion) { + return chartName + "_" + chartVersion; + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/Application.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/Application.java deleted file mode 100644 index 5d9d203fe..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/Application.java +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.kubernetes; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.context.properties.ConfigurationPropertiesScan; -import org.springframework.context.annotation.ComponentScan; - -/** - * Starter. - * - */ -@SpringBootApplication -@ComponentScan({"org.onap.policy.clamp.controlloop.participant.kubernetes", - "org.onap.policy.clamp.controlloop.participant.intermediary"}) -@ConfigurationPropertiesScan("org.onap.policy.clamp.controlloop.participant.kubernetes.parameters") -public class Application { - /** - * Main class. - * - * @param args args - */ - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParticipantConfig.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParticipantConfig.java deleted file mode 100644 index 54627d557..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParticipantConfig.java +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * Copyright (C) 2021 Nordix Foundation. All rights reserved. - * ====================================================================== - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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.onap.policy.clamp.controlloop.participant.kubernetes.configurations; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.multipart.MultipartResolver; -import org.springframework.web.multipart.commons.CommonsMultipartResolver; - -/** - * Bean Factory class for helm client. - */ -@Configuration -public class ParticipantConfig { - - /** - * Method to create multipartResolver bean. - * @return MultipartResolver - */ - @Bean(name = "multipartResolver") - public MultipartResolver multipartResolver() { - var multipartResolver = new CommonsMultipartResolver(); - multipartResolver.setMaxUploadSize(100000); - return multipartResolver; - } -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParticipantIntermediaryConfig.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParticipantIntermediaryConfig.java deleted file mode 100644 index bfbed66b7..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParticipantIntermediaryConfig.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.kubernetes.configurations; - -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.clamp.controlloop.participant.kubernetes.handler.ControlLoopElementHandler; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class ParticipantIntermediaryConfig { - - /** - * Register ControlLoopElementListener. - * - * @param intermediaryApi the ParticipantIntermediaryApi - * @param clElementHandler the ControlLoop Element Handler - */ - @Autowired - public void registerControlLoopElementListener(ParticipantIntermediaryApi intermediaryApi, - ControlLoopElementHandler clElementHandler) { - intermediaryApi.registerControlLoopElementListener(clElementHandler); - clElementHandler.setIntermediaryApi(intermediaryApi); - } -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/SecurityConfig.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/SecurityConfig.java deleted file mode 100644 index 6b4fb0a75..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/SecurityConfig.java +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.kubernetes.configurations; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@Configuration -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Value("${security.enable-csrf:true}") - private boolean csrfEnabled = true; - - @Override - protected void configure(HttpSecurity http) throws Exception { - // @formatter:off - http.authorizeRequests() - .antMatchers().authenticated() - .anyRequest().authenticated() - .and().httpBasic(); - // @formatter:on - - if (!csrfEnabled) { - http.csrf().disable(); - } - } -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/SpringFoxConfig.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/SpringFoxConfig.java deleted file mode 100644 index 09a497705..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/SpringFoxConfig.java +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.kubernetes.configurations; - -import org.onap.policy.clamp.controlloop.participant.kubernetes.controller.ChartController; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; - -@Configuration -public class SpringFoxConfig { - - /** - * Docket Spring Fox Config. - * - * @return Docket - */ - @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2).select() - .apis(RequestHandlerSelectors.basePackage(ChartController.class.getPackageName())) - .paths(PathSelectors.any()).build(); - } -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/controller/ChartController.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/controller/ChartController.java deleted file mode 100644 index e2ccda4d5..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/controller/ChartController.java +++ /dev/null @@ -1,195 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * Copyright (C) 2021-2022 Nordix Foundation. All rights reserved. - * ====================================================================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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.onap.policy.clamp.controlloop.participant.kubernetes.controller; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import java.io.IOException; -import java.util.ArrayList; -import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartList; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.HelmRepository; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.InstallationInfo; -import org.onap.policy.clamp.controlloop.participant.kubernetes.service.ChartService; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; -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.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -@RestController("chartController") -@ConditionalOnExpression("${chart.api.enabled:false}") -@RequestMapping("helm") -@Api(tags = {"k8s-participant"}) -public class ChartController { - - @Autowired - private ChartService chartService; - - private static final StandardCoder CODER = new StandardCoder(); - - /** - * REST endpoint to get all the charts. - * - * @return List of charts installed - */ - @GetMapping(path = "/charts", produces = MediaType.APPLICATION_JSON_VALUE) - @ApiOperation(value = "Return all Charts") - @ApiResponses(value = {@ApiResponse(code = 200, message = "chart List")}) - public ResponseEntity getAllCharts() { - return new ResponseEntity<>(ChartList.builder().charts(new ArrayList<>(chartService.getAllCharts())).build(), - HttpStatus.OK); - } - - /** - * REST endpoint to install a helm chart. - * - * @param info Info of the chart to be installed - * @return Status of the install operation - * @throws ServiceException in case of error - * @throws IOException in case of IO error - */ - @PostMapping(path = "/install", consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - @ApiOperation(value = "Install the chart") - @ApiResponses(value = {@ApiResponse(code = 201, message = "chart Installed")}) - public ResponseEntity installChart(@RequestBody InstallationInfo info) - throws ServiceException, IOException { - ChartInfo chart = chartService.getChart(info.getName(), info.getVersion()); - if (chart == null) { - return new ResponseEntity<>(HttpStatus.NOT_FOUND); - } - - chartService.installChart(chart); - return new ResponseEntity<>(HttpStatus.CREATED); - } - - /** - * REST endpoint to uninstall a specific chart. - * - * @param name name of the chart - * @param version version of the chart - * @return Status of operation - * @throws ServiceException in case of error. - */ - @DeleteMapping(path = "/uninstall/{name}/{version}", produces = MediaType.APPLICATION_JSON_VALUE) - @ApiOperation(value = "Uninstall the Chart") - @ApiResponses(value = {@ApiResponse(code = 201, message = "chart Uninstalled")}) - public ResponseEntity uninstallChart(@PathVariable("name") String name, - @PathVariable("version") String version) throws ServiceException { - ChartInfo chart = chartService.getChart(name, version); - if (chart == null) { - return new ResponseEntity<>(HttpStatus.NOT_FOUND); - } - - chartService.uninstallChart(chart); - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } - - /** - * REST endpoint to onboard a chart. - * - * @param chartFile Multipart file for the helm chart - * @param infoJson AppInfo of the chart - * @param overrideFile the file for overriding the chart - * @return Status of onboard operation - * @throws ServiceException in case of error - * @throws IOException in case of IO error - */ - @PostMapping(path = "/onboard/chart", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - @ApiOperation(value = "Onboard the Chart") - @ApiResponses(value = {@ApiResponse(code = 201, message = "Chart Onboarded")}) - public ResponseEntity onboardChart(@RequestPart("chart") MultipartFile chartFile, - @RequestParam(name = "values", required = false) MultipartFile overrideFile, - @RequestParam("info") String infoJson) throws ServiceException, IOException { - - ChartInfo info; - try { - info = CODER.decode(infoJson, ChartInfo.class); - } catch (CoderException e) { - throw new ServiceException("Error parsing the chart information", e); - } - - chartService.saveChart(info, chartFile, overrideFile); - return new ResponseEntity<>(HttpStatus.OK); - } - - /** - * REST endpoint to delete a specific helm chart. - * - * @param name name of the chart - * @param version version of the chart - * @return Status of operation - */ - @DeleteMapping(path = "/chart/{name}/{version}") - @ApiOperation(value = "Delete the chart") - @ApiResponses(value = {@ApiResponse(code = 204, message = "Chart Deleted")}) - public ResponseEntity deleteChart(@PathVariable("name") String name, - @PathVariable("version") String version) { - - ChartInfo chart = chartService.getChart(name, version); - if (chart == null) { - return new ResponseEntity<>(HttpStatus.NOT_FOUND); - } - - chartService.deleteChart(chart); - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } - - /** - * REST endpoint to configure a helm Repository. - * - * @param repo Helm repository to be configured - * @return Status of the operation - * @throws ServiceException in case of error - * @throws IOException in case of IO error - */ - @PostMapping(path = "/repo", consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - @ApiOperation(value = "Configure helm repository") - @ApiResponses(value = {@ApiResponse(code = 201, message = "Repository added")}) - public ResponseEntity configureRepo(@RequestBody String repo) - throws ServiceException, IOException { - HelmRepository repository; - try { - repository = CODER.decode(repo, HelmRepository.class); - } catch (CoderException e) { - throw new ServiceException("Error parsing the repository information", e); - } - chartService.configureRepository(repository); - - return new ResponseEntity<>(HttpStatus.CREATED); - } -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/exception/ServiceException.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/exception/ServiceException.java deleted file mode 100644 index 9a825cf75..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/exception/ServiceException.java +++ /dev/null @@ -1,32 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.kubernetes.exception; - -public class ServiceException extends Exception { - - private static final long serialVersionUID = 6810785674716590648L; - - public ServiceException(String message) { - super(message); - } - - public ServiceException(String message, Exception originalException) { - super(message, originalException); - } -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java deleted file mode 100644 index a8a746254..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java +++ /dev/null @@ -1,196 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 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.onap.policy.clamp.controlloop.participant.kubernetes.handler; - -import java.io.IOException; -import java.lang.invoke.MethodHandles; -import java.time.Instant; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.Setter; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; -import org.onap.policy.clamp.controlloop.participant.kubernetes.helm.PodStatusValidator; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; -import org.onap.policy.clamp.controlloop.participant.kubernetes.service.ChartService; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -/** - * This class handles implementation of controlLoopElement updates. - */ -@Component -public class ControlLoopElementHandler implements ControlLoopElementListener { - private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - - private ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); - - // Map of helm installation and the status of corresponding pods - @Getter - private static Map> podStatusMap = new ConcurrentHashMap<>(); - private static final Coder CODER = new StandardCoder(); - - @Autowired - private ChartService chartService; - - @Setter - private ParticipantIntermediaryApi intermediaryApi; - - // Map of CLElement Id and installed Helm charts - @Getter(AccessLevel.PACKAGE) - private final Map chartMap = new HashMap<>(); - - // Default thread config values - private static class ThreadConfig { - private int uninitializedToPassiveTimeout = 60; - private int podStatusCheckInterval = 30; - } - - /** - * Callback method to handle a control loop element state change. - * - * @param controlLoopElementId the ID of the control loop element - * @param currentState the current state of the control loop element - * @param newState the state to which the control loop element is changing to - */ - @Override - public synchronized void controlLoopElementStateChange(ToscaConceptIdentifier controlLoopId, - UUID controlLoopElementId, ControlLoopState currentState, ControlLoopOrderedState newState) { - switch (newState) { - case UNINITIALISED: - ChartInfo chart = chartMap.get(controlLoopElementId); - if (chart != null) { - LOGGER.info("Helm deployment to be deleted {} ", chart.getReleaseName()); - try { - chartService.uninstallChart(chart); - intermediaryApi.updateControlLoopElementState(controlLoopId, - controlLoopElementId, newState, ControlLoopState.UNINITIALISED, - ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); - chartMap.remove(controlLoopElementId); - podStatusMap.remove(chart.getReleaseName()); - } catch (ServiceException se) { - LOGGER.warn("Deletion of Helm deployment failed", se); - } - } - break; - case PASSIVE: - intermediaryApi.updateControlLoopElementState(controlLoopId, - controlLoopElementId, newState, ControlLoopState.PASSIVE, - ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); - break; - case RUNNING: - intermediaryApi.updateControlLoopElementState(controlLoopId, - controlLoopElementId, newState, ControlLoopState.RUNNING, - ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); - break; - default: - LOGGER.warn("Cannot transition from state {} to state {}", currentState, newState); - break; - } - } - - - /** - * Callback method to handle an update on a control loop element. - * - * @param element the information on the control loop element - * @param nodeTemplate toscaNodeTemplate - * @throws PfModelException in case of an exception - */ - @Override - public synchronized void controlLoopElementUpdate(ToscaConceptIdentifier controlLoopId, - ControlLoopElement element, ToscaNodeTemplate nodeTemplate) throws PfModelException { - @SuppressWarnings("unchecked") - Map chartData = - (Map) nodeTemplate.getProperties().get("chart"); - - LOGGER.info("Installation request received for the Helm Chart {} ", chartData); - try { - var chartInfo = CODER.convert(chartData, ChartInfo.class); - chartService.installChart(chartInfo); - chartMap.put(element.getId(), chartInfo); - - var config = CODER.convert(nodeTemplate.getProperties(), ThreadConfig.class); - checkPodStatus(controlLoopId, element.getId(), chartInfo, config.uninitializedToPassiveTimeout, - config.podStatusCheckInterval); - - } catch (ServiceException | CoderException | IOException | ExecutionException - | InterruptedException e) { - LOGGER.warn("Installation of Helm chart failed", e); - } - } - - /** - * Invoke a new thread to check the status of deployed pods. - * @param chart ChartInfo - */ - public void checkPodStatus(ToscaConceptIdentifier controlLoopId, UUID elementId, - ChartInfo chart, int timeout, int podStatusCheckInterval) throws ExecutionException, InterruptedException { - // Invoke runnable thread to check pod status - Future result = executor.submit(new PodStatusValidator(chart, timeout, - podStatusCheckInterval), "Done"); - if (!result.get().isEmpty()) { - LOGGER.info("Pod Status Validator Completed: {}", result.isDone()); - intermediaryApi.updateControlLoopElementState(controlLoopId, elementId, - ControlLoopOrderedState.PASSIVE, ControlLoopState.PASSIVE, - ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); - } - } - - /** - * Overridden method. - * - * @param controlLoopElementId controlLoopElement id - * @throws PfModelException in case of error - */ - @Override - public synchronized void handleStatistics(UUID controlLoopElementId) throws PfModelException { - var clElement = intermediaryApi.getControlLoopElement(controlLoopElementId); - if (clElement != null) { - var clElementStatistics = new ClElementStatistics(); - clElementStatistics.setControlLoopState(clElement.getState()); - clElementStatistics.setTimeStamp(Instant.now()); - intermediaryApi.updateControlLoopElementStatistics(controlLoopElementId, clElementStatistics); - } - } -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClient.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClient.java deleted file mode 100644 index 6133c7ebd..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClient.java +++ /dev/null @@ -1,279 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * Copyright (C) 2021-2022 Nordix Foundation. All rights reserved. - * ====================================================================== - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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.onap.policy.clamp.controlloop.participant.kubernetes.helm; - -import java.io.File; -import java.io.IOException; -import java.lang.invoke.MethodHandles; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import org.apache.commons.io.IOUtils; -import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.HelmRepository; -import org.onap.policy.clamp.controlloop.participant.kubernetes.service.ChartStore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -/** - * Client to talk with Helm cli. Supports helm3 + version - */ -@Component -public class HelmClient { - - @Autowired - private ChartStore chartStore; - - private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - private static final String PATH_DELIMITER = "/"; - - /** - * Install a chart. - * - * @param chart name and version. - * @throws ServiceException incase of error - */ - public void installChart(ChartInfo chart) throws ServiceException { - if (! checkNamespaceExists(chart.getNamespace())) { - var processBuilder = prepareCreateNamespaceCommand(chart.getNamespace()); - executeCommand(processBuilder); - } - var processBuilder = prepareInstallCommand(chart); - logger.info("Installing helm chart {} from the repository {} ", chart.getChartId().getName(), - chart.getRepository().getRepoName()); - executeCommand(processBuilder); - logger.info("Chart {} installed successfully", chart.getChartId().getName()); - } - - /** - * Add repository if doesn't exist. - * @param repo HelmRepository - * @throws ServiceException incase of error - */ - public void addRepository(HelmRepository repo) throws ServiceException { - String output = executeCommand(prepareVerifyRepoCommand(repo)); - if (output.isEmpty()) { - logger.info("Adding repository to helm client"); - executeCommand(prepareRepoAddCommand(repo)); - logger.debug("Added repository {} to the helm client", repo.getRepoName()); - } else { - logger.info("Repository already exists"); - } - } - - - /** - * Finds helm chart repository for the chart. - * - * @param chart ChartInfo. - * @return the chart repository as a string - * @throws ServiceException in case of error - * @throws IOException in case of IO errors - */ - public String findChartRepository(ChartInfo chart) throws ServiceException, IOException { - if (updateHelmRepo()) { - String repository = verifyConfiguredRepo(chart); - if (repository != null) { - logger.info("Helm chart located in the repository {} ", repository); - return repository; - } - } - var localHelmChartDir = chartStore.getAppPath(chart.getChartId()).toString(); - logger.info("Chart not found in helm repositories, verifying local repo {} ", localHelmChartDir); - if (verifyLocalHelmRepo(new File(localHelmChartDir + PATH_DELIMITER + chart.getChartId().getName()))) { - return localHelmChartDir; - } - return null; - } - - /** - * Verify helm chart in configured repositories. - * @param chart chartInfo - * @return repo name - * @throws IOException incase of error - * @throws ServiceException incase of error - */ - public String verifyConfiguredRepo(ChartInfo chart) throws IOException, ServiceException { - logger.info("Looking for helm chart {} in all the configured helm repositories", chart.getChartId().getName()); - String repository = null; - var builder = helmRepoVerifyCommand(chart.getChartId().getName()); - String output = executeCommand(builder); - repository = verifyOutput(output, chart.getChartId().getName()); - return repository; - } - - /** - * Uninstall a chart. - * - * @param chart name and version. - * @throws ServiceException incase of error - */ - public void uninstallChart(ChartInfo chart) throws ServiceException { - executeCommand(prepareUnInstallCommand(chart)); - } - - - /** - * Execute helm cli bash commands . - * @param processBuilder processbuilder - * @return string output - * @throws ServiceException incase of error. - */ - public static String executeCommand(ProcessBuilder processBuilder) throws ServiceException { - var commandStr = toString(processBuilder); - - try { - var process = processBuilder.start(); - process.waitFor(); - int exitValue = process.exitValue(); - - if (exitValue != 0) { - var error = IOUtils.toString(process.getErrorStream(), StandardCharsets.UTF_8); - if (! error.isEmpty()) { - throw new ServiceException("Command execution failed: " + commandStr + " " + error); - } - } - - var output = IOUtils.toString(process.getInputStream(), StandardCharsets.UTF_8); - logger.debug("Command <{}> execution, output: {}", commandStr, output); - return output; - - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - throw new ServiceException("Failed to execute the Command: " + commandStr + ", the command was interrupted", - ie); - } catch (Exception exc) { - throw new ServiceException("Failed to execute the Command: " + commandStr, exc); - } - } - - private boolean checkNamespaceExists(String namespace) throws ServiceException { - logger.info("Check if namespace {} exists on the cluster", namespace); - String output = executeCommand(prepareVerifyNamespaceCommand(namespace)); - return !output.isEmpty(); - } - - private String verifyOutput(String output, String value) { - for (var line: output.split("\\R")) { - if (line.contains(value)) { - return line.split("/")[0]; - } - } - return null; - } - - private ProcessBuilder prepareRepoAddCommand(HelmRepository repo) { - var url = repo.getProtocol() + "://" + repo.getAddress(); - if (repo.getPort() != null) { - url = url + ":" + repo.getPort(); - } - // @formatter:off - List helmArguments = new ArrayList<>( - List.of( - "helm", - "repo", - "add", repo.getRepoName(), url - )); - if (repo.getUserName() != null && repo.getPassword() != null) { - helmArguments.addAll(List.of("--username", repo.getUserName(), "--password", repo.getPassword())); - } - return new ProcessBuilder().command(helmArguments); - } - - private ProcessBuilder prepareVerifyRepoCommand(HelmRepository repo) { - List helmArguments = List.of("sh", "-c", "helm repo ls | grep " + repo.getRepoName()); - return new ProcessBuilder().command(helmArguments); - } - - private ProcessBuilder prepareVerifyNamespaceCommand(String namespace) { - List helmArguments = List.of("sh", "-c", "kubectl get ns | grep " + namespace); - return new ProcessBuilder().command(helmArguments); - } - - private ProcessBuilder prepareInstallCommand(ChartInfo chart) { - - // @formatter:off - List helmArguments = new ArrayList<>( - List.of( - "helm", - "install", chart.getReleaseName(), chart.getRepository().getRepoName() + "/" - + chart.getChartId().getName(), - "--version", chart.getChartId().getVersion(), - "--namespace", chart.getNamespace() - )); - // @formatter:on - - // Verify if values.yaml/override parameters available for the chart - var localOverrideYaml = chartStore.getOverrideFile(chart); - - if (verifyLocalHelmRepo(localOverrideYaml)) { - logger.info("Override yaml available for the helm chart"); - helmArguments.addAll(List.of("--values", localOverrideYaml.getPath())); - } - - if (chart.getOverrideParams() != null) { - for (Map.Entry entry : chart.getOverrideParams().entrySet()) { - helmArguments.addAll(List.of("--set", entry.getKey() + "=" + entry.getValue())); - } - } - return new ProcessBuilder().command(helmArguments); - } - - private ProcessBuilder prepareUnInstallCommand(ChartInfo chart) { - return new ProcessBuilder("helm", "delete", chart.getReleaseName(), "--namespace", - chart.getNamespace()); - } - - private ProcessBuilder prepareCreateNamespaceCommand(String namespace) { - return new ProcessBuilder().command("kubectl", "create", "namespace", namespace); - } - - private ProcessBuilder helmRepoVerifyCommand(String chartName) { - return new ProcessBuilder().command("sh", "-c", "helm search repo | grep " + chartName); - } - - - private boolean updateHelmRepo() { - try { - logger.info("Updating local helm repositories before verifying the chart"); - executeCommand(new ProcessBuilder().command("helm", "repo", "update")); - logger.debug("Helm repositories updated successfully"); - } catch (ServiceException e) { - logger.error("Failed to update the helm repo: ", e); - return false; - } - return true; - - - } - - private boolean verifyLocalHelmRepo(File localFile) { - return localFile.exists(); - } - - protected static String toString(ProcessBuilder processBuilder) { - return String.join(" ", processBuilder.command()); - } -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/PodStatusValidator.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/PodStatusValidator.java deleted file mode 100644 index d55fd6658..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/PodStatusValidator.java +++ /dev/null @@ -1,119 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.kubernetes.helm; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.lang.invoke.MethodHandles; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Map; -import lombok.SneakyThrows; -import org.apache.commons.io.IOUtils; -import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; -import org.onap.policy.clamp.controlloop.participant.kubernetes.handler.ControlLoopElementHandler; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public class PodStatusValidator implements Runnable { - - private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - - private final int statusCheckInterval; - - //Timeout for the thread to exit. - private final int timeout; - - private ChartInfo chart; - - /** - * Constructor for PodStatusValidator. - * @param chart chartInfo - * @param timeout timeout for the thread to exit - * @param statusCheckInterval Interval to check pod status - */ - public PodStatusValidator(ChartInfo chart, int timeout, int statusCheckInterval) { - this.chart = chart; - this.timeout = timeout; - this.statusCheckInterval = statusCheckInterval; - } - - - @SneakyThrows - @Override - public void run() { - logger.info("Polling the status of deployed pods for the chart {}", chart.getChartId().getName()); - Map podStatusMap; - String output = null; - var isVerified = false; - long endTime = System.currentTimeMillis() + (timeout * 1000L); - - while (!isVerified && System.currentTimeMillis() < endTime) { - try { - output = HelmClient.executeCommand(verifyPodStatusCommand(chart)); - podStatusMap = mapPodStatus(output); - isVerified = podStatusMap.values() - .stream() - .allMatch("Running"::equals); - if (! isVerified) { - logger.info("Waiting for the pods to be active for the chart {}", chart.getChartId().getName()); - podStatusMap.forEach((key, value) -> logger.info("Pod: {} , state: {}", key, value)); - ControlLoopElementHandler.getPodStatusMap().put(chart.getReleaseName(), podStatusMap); - // Recheck status of pods in specific intervals. - Thread.sleep(statusCheckInterval * 1000L); - } else { - logger.info("All pods are in running state for the helm chart {}", chart.getChartId().getName()); - ControlLoopElementHandler.getPodStatusMap().put(chart.getReleaseName(), podStatusMap); - } - } catch (ServiceException | IOException e) { - throw new ServiceException("Error verifying the status of the pod. Exiting", e); - } - } - } - - private ProcessBuilder verifyPodStatusCommand(ChartInfo chart) { - String podName = chart.getReleaseName() + "-" + chart.getChartId().getName(); - String cmd = "kubectl get pods --namespace " + chart.getNamespace() + " | grep " + podName; - return new ProcessBuilder("sh", "-c", cmd); - } - - - private Map mapPodStatus(String output) throws IOException, ServiceException { - Map podStatusMap = new HashMap<>(); - try (var reader = new BufferedReader(new InputStreamReader(IOUtils.toInputStream(output, - StandardCharsets.UTF_8)))) { - var line = reader.readLine(); - while (line != null) { - if (line.contains(chart.getChartId().getName())) { - var result = line.split("\\s+"); - podStatusMap.put(result[0], result[2]); - } - line = reader.readLine(); - } - } - if (!podStatusMap.isEmpty()) { - return podStatusMap; - } else { - throw new ServiceException("Status of Pod is empty"); - } - } -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartInfo.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartInfo.java deleted file mode 100644 index 5cbc203ec..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartInfo.java +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.kubernetes.models; - -import java.util.Map; -import lombok.Data; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; - -@Data -@RequiredArgsConstructor -public class ChartInfo { - - @NonNull - private String releaseName; - - @NonNull - private ToscaConceptIdentifier chartId; - - @NonNull - private String namespace; - - private HelmRepository repository; - - private Map overrideParams; - -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartList.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartList.java deleted file mode 100644 index 7f46bbde5..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartList.java +++ /dev/null @@ -1,31 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.kubernetes.models; - -import java.util.List; -import lombok.Builder; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Builder -public class ChartList { - private List charts; -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/HelmRepository.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/HelmRepository.java deleted file mode 100644 index a495c7b5c..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/HelmRepository.java +++ /dev/null @@ -1,39 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.kubernetes.models; - -import lombok.Builder; -import lombok.Data; - -@Data -@Builder -public class HelmRepository { - - private String repoName; - - private String protocol; - - private String address; - - private String port; - - private String userName; - - private String password; -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/InstallationInfo.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/InstallationInfo.java deleted file mode 100644 index b21e93a01..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/InstallationInfo.java +++ /dev/null @@ -1,29 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.kubernetes.models; - -import lombok.Getter; -import org.immutables.gson.Gson; - -@Getter -@Gson.TypeAdapters -public class InstallationInfo { - private String name; - private String version; -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParameters.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParameters.java deleted file mode 100644 index 3b2b3732b..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParameters.java +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.kubernetes.parameters; - -import javax.validation.Valid; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import lombok.Getter; -import lombok.Setter; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.validation.annotation.Validated; - -/** - * Class to hold all parameters needed for the kubernetes participant. - * - */ -@Validated -@Getter -@Setter -@ConfigurationProperties(prefix = "participant") -public class ParticipantK8sParameters implements ParticipantParameters { - - @NotNull - @Valid - private ParticipantIntermediaryParameters intermediaryParameters; - - @NotBlank - private String localChartDirectory; - - @NotBlank - private String infoFileName; -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartService.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartService.java deleted file mode 100644 index a07fca596..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartService.java +++ /dev/null @@ -1,141 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.kubernetes.service; - -import java.io.IOException; -import java.lang.invoke.MethodHandles; -import java.util.Collection; -import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; -import org.onap.policy.clamp.controlloop.participant.kubernetes.helm.HelmClient; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.HelmRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; - -@Service -public class ChartService { - private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - - @Autowired - private ChartStore chartStore; - - @Autowired - private HelmClient helmClient; - - /** - * Get all the installed charts. - * @return list of charts. - */ - public Collection getAllCharts() { - return chartStore.getAllCharts(); - } - - /** - * Get specific chart info. - * @param name name of the app - * @param version version of the app - * @return chart - */ - public ChartInfo getChart(String name, String version) { - return chartStore.getChart(name, version); - } - - /** - * Save a helm chart. - * @param chartInfo name and version of the app. - * @param chartFile Helm chart file - * @param overrideFile override file - * @return chart details of the helm chart - * @throws IOException in case of IO error - * @throws ServiceException in case of error - */ - public ChartInfo saveChart(ChartInfo chartInfo, MultipartFile chartFile, MultipartFile overrideFile) - throws IOException, ServiceException { - return chartStore.saveChart(chartInfo, chartFile, overrideFile); - } - - /** - * Delete a helm chart. - * @param chart name and version of the chart. - */ - public void deleteChart(ChartInfo chart) { - chartStore.deleteChart(chart); - } - - /** - * Install a helm chart. - * @param chart name and version. - * @throws ServiceException in case of error - * @throws IOException in case of IO errors - */ - public void installChart(ChartInfo chart) throws ServiceException, IOException { - if (chart.getRepository() == null) { - String repoName = findChartRepo(chart); - if (repoName == null) { - logger.error("Chart repository could not be found. Skipping chart Installation " - + "for the chart {} ", chart.getChartId().getName()); - return; - } else { - HelmRepository repo = HelmRepository.builder().repoName(repoName).build(); - chart.setRepository(repo); - } - } else { - // Add remote repository if passed via TOSCA - configureRepository(chart.getRepository()); - } - helmClient.installChart(chart); - } - - - /** - * Configure remote repository. - * @param repo HelmRepository - * @throws ServiceException incase of error - */ - public void configureRepository(HelmRepository repo) throws ServiceException { - if (repo.getAddress() != null) { - helmClient.addRepository(repo); - } - } - - /** - * Finds helm chart repository for a given chart. - * @param chart chartInfo. - * @return the chart repo as a string - * @throws ServiceException in case of error - * @throws IOException in case of IO errors - */ - public String findChartRepo(ChartInfo chart) throws ServiceException, IOException { - logger.info("Fetching helm chart repository for the given chart {} ", chart.getChartId().getName()); - return helmClient.findChartRepository(chart); - } - - /** - * Uninstall a helm chart. - * @param chart name and version - * @throws ServiceException in case of error. - */ - public void uninstallChart(ChartInfo chart) throws ServiceException { - logger.info("Uninstalling helm deployment {}", chart.getReleaseName()); - helmClient.uninstallChart(chart); - } -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartStore.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartStore.java deleted file mode 100644 index ed53d0352..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartStore.java +++ /dev/null @@ -1,219 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * Copyright (C) 2021 Nordix Foundation. All rights reserved. - * ====================================================================== - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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.onap.policy.clamp.controlloop.participant.kubernetes.service; - -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.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import lombok.AccessLevel; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; -import org.onap.policy.clamp.controlloop.participant.kubernetes.parameters.ParticipantK8sParameters; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; -import org.springframework.util.FileSystemUtils; -import org.springframework.web.multipart.MultipartFile; - -@Component -public class ChartStore { - private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - - private static final StandardCoder STANDARD_CODER = new StandardCoder(); - - private final ParticipantK8sParameters participantK8sParameters; - - // ChartStore map contains chart name as key & ChartInfo as value. - @Getter(AccessLevel.PACKAGE) - private Map localChartMap = new ConcurrentHashMap<>(); - - /** - * Constructor method. - */ - public ChartStore(ParticipantK8sParameters participantK8sParameters) { - this.participantK8sParameters = participantK8sParameters; - this.restoreFromLocalFileSystem(); - } - - /** - * Get local helm chart file. - * - * @param chart ChartInfo - * @return the chart file. - */ - public File getHelmChartFile(ChartInfo chart) { - var appPath = getAppPath(chart.getChartId()); - return new File(appPath.toFile(), chart.getChartId().getName()); - } - - /** - * Get the override yaml file. - * - * @param chart ChartInfo - * @return the override yaml file - */ - public File getOverrideFile(ChartInfo chart) { - var appPath = getAppPath(chart.getChartId()); - return new File(appPath.toFile(), "values.yaml"); - } - - - /** - * Saves the helm chart. - * - * @param chartInfo chartInfo - * @param chartFile helm chart file. - * @param overrideFile override file. - * @return chart - * @throws IOException incase of IO error - * @throws ServiceException incase of error. - */ - public synchronized ChartInfo saveChart(ChartInfo chartInfo, MultipartFile chartFile, MultipartFile overrideFile) - throws IOException, ServiceException { - if (localChartMap.containsKey(key(chartInfo))) { - throw new ServiceException("Chart already exist"); - } - var appPath = getAppPath(chartInfo.getChartId()); - Files.createDirectories(appPath); - - chartFile.transferTo(getHelmChartFile(chartInfo)); - if (overrideFile != null) { - overrideFile.transferTo(getOverrideFile(chartInfo)); - } - - localChartMap.put(key(chartInfo), chartInfo); - storeChartInFile(chartInfo); - return chartInfo; - } - - /** - * Get the chart info. - * - * @param name name of the chart - * @param version version of the chart - * @return chart - */ - public synchronized ChartInfo getChart(String name, String version) { - return localChartMap.get(key(name, version)); - } - - /** - * Get all the charts installed. - * - * @return list of charts. - */ - public synchronized List getAllCharts() { - return new ArrayList<>(localChartMap.values()); - } - - /** - * Delete a chart. - * - * @param chart chart info - */ - public synchronized void deleteChart(ChartInfo chart) { - var appPath = getAppPath(chart.getChartId()); - try { - FileSystemUtils.deleteRecursively(appPath); - } catch (IOException exc) { - LOGGER.warn("Could not delete chart from local file system : {}", appPath, exc); - } - - localChartMap.remove(key(chart)); - } - - /** - * Fetch the local chart directory of specific chart. - * - * @param chartId Id of the chart - * @return path - */ - public Path getAppPath(ToscaConceptIdentifier chartId) { - return Path.of(participantK8sParameters.getLocalChartDirectory(), chartId.getName(), chartId.getVersion()); - } - - private void storeChartInFile(ChartInfo chart) { - try (var out = new PrintStream(new FileOutputStream(getFile(chart)))) { - out.print(STANDARD_CODER.encode(chart)); - } catch (Exception exc) { - LOGGER.warn("Could not store chart: {}", chart.getChartId(), exc); - } - } - - private File getFile(ChartInfo chart) { - var appPath = getAppPath(chart.getChartId()).toString(); - return Path.of(appPath, participantK8sParameters.getInfoFileName()).toFile(); - } - - private synchronized void restoreFromLocalFileSystem() { - try { - var localChartDirectoryPath = Paths.get(participantK8sParameters.getLocalChartDirectory()); - Files.createDirectories(localChartDirectoryPath); - restoreFromLocalFileSystem(localChartDirectoryPath); - } catch (Exception ioe) { - LOGGER.warn("Could not restore charts from local file system", ioe); - } - } - - private synchronized void restoreFromLocalFileSystem(Path localChartDirectoryPath) - throws IOException { - - Files.walkFileTree(localChartDirectoryPath, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path localChartFile, BasicFileAttributes attrs) throws IOException { - try { - // Decode only the json file excluding the helm charts - if (localChartFile.endsWith(participantK8sParameters.getInfoFileName())) { - ChartInfo chart = STANDARD_CODER.decode(localChartFile.toFile(), ChartInfo.class); - localChartMap.put(key(chart), chart); - } - return FileVisitResult.CONTINUE; - } catch (CoderException ce) { - throw new IOException("Error decoding chart file", ce); - } - } - }); - } - - private String key(ChartInfo chart) { - return key(chart.getChartId().getName(), chart.getChartId().getVersion()); - } - - private String key(String chartName, String chartVersion) { - return chartName + "_" + chartVersion; - } -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/application.yaml b/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/application.yaml index b266fe337..3be0fb2c0 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/application.yaml +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/application.yaml @@ -13,22 +13,22 @@ participant: reportingTimeIntervalMs: 120000 description: Participant Description participantId: - name: K8sParticipant0 - version: 1.0.0 + name: org.onap.policy.clamp.acm.KubernetesParticipant + version: 2.3.4 participantType: - name: org.onap.k8s.controlloop.K8sControlLoopParticipant + name: org.onap.k8s.acm.K8SAutomationCompositionParticipant version: 2.3.4 - clampControlLoopTopics: + clampAutomationCompositionTopics: topicSources: - - topic: POLICY-CLRUNTIME-PARTICIPANT + topic: POLICY-ACRUNTIME-PARTICIPANT servers: - ${topicServer:localhost} topicCommInfrastructure: dmaap fetchTimeout: 15000 topicSinks: - - topic: POLICY-CLRUNTIME-PARTICIPANT + topic: POLICY-ACRUNTIME-PARTICIPANT servers: - ${topicServer:localhost} topicCommInfrastructure: dmaap @@ -41,7 +41,7 @@ management: server: port: 8083 servlet: - context-path: /onap/k8sparticipant + context-path: /onap/policy/clamp/acm/k8sparticipant logging: # Configuration of logging @@ -50,7 +50,7 @@ logging: org.springframework: ERROR org.springframework.data: ERROR org.springframework.web.reactive.function.client.ExchangeFunctions: ERROR - org.onap.policy.clamp.controlloop.participant.kubernetes: INFO + org.onap.policy.clamp.acm.participant.kubernetes: INFO file: name: /var/log/onap/policy/clamp/application.log diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandlerTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandlerTest.java new file mode 100644 index 000000000..dc74afc1a --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandlerTest.java @@ -0,0 +1,182 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.kubernetes.handler; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartList; +import org.onap.policy.clamp.acm.participant.kubernetes.parameters.CommonTestData; +import org.onap.policy.clamp.acm.participant.kubernetes.service.ChartService; +import org.onap.policy.clamp.acm.participant.kubernetes.utils.TestUtils; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +class AutomationCompositionElementHandlerTest { + + private static final Coder CODER = new StandardCoder(); + private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; + private static final String KEY_NAME = + "org.onap.domain.database.HelloWorld_K8SMicroserviceAutomationCompositionElement"; + private static List charts; + private static ToscaServiceTemplate toscaServiceTemplate; + private static final String K8S_AUTOMATION_COMPOSITION_ELEMENT = + "org.onap.domain.database.PMSH_K8SMicroserviceAutomationCompositionElement"; + private CommonTestData commonTestData = new CommonTestData(); + + @InjectMocks + @Spy + private AutomationCompositionElementHandler automationCompositionElementHandler = + new AutomationCompositionElementHandler(); + + @Mock + private ChartService chartService; + + @Mock + private ParticipantIntermediaryApi participantIntermediaryApi; + + @Mock + private ExecutorService executor; + @Mock + private Future result; + + @BeforeAll + static void init() throws CoderException { + charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); + toscaServiceTemplate = TestUtils.testAutomationCompositionRead(); + } + + @Test + void test_AutomationCompositionElementStateChange() throws ServiceException { + UUID automationCompositionElementId1 = UUID.randomUUID(); + UUID automationCompositionElementId2 = UUID.randomUUID(); + + automationCompositionElementHandler.getChartMap().put(automationCompositionElementId1, charts.get(0)); + automationCompositionElementHandler.getChartMap().put(automationCompositionElementId2, charts.get(1)); + + doNothing().when(chartService).uninstallChart(charts.get(0)); + + automationCompositionElementHandler.automationCompositionElementStateChange( + commonTestData.getAutomationCompositionId(), automationCompositionElementId1, + AutomationCompositionState.PASSIVE, AutomationCompositionOrderedState.UNINITIALISED); + + doThrow(new ServiceException("Error uninstalling the chart")).when(chartService).uninstallChart(charts.get(0)); + + assertDoesNotThrow(() -> automationCompositionElementHandler.automationCompositionElementStateChange( + commonTestData.getAutomationCompositionId(), automationCompositionElementId1, + AutomationCompositionState.PASSIVE, AutomationCompositionOrderedState.PASSIVE)); + + assertDoesNotThrow(() -> automationCompositionElementHandler.automationCompositionElementStateChange( + commonTestData.getAutomationCompositionId(), automationCompositionElementId1, + AutomationCompositionState.PASSIVE, AutomationCompositionOrderedState.UNINITIALISED)); + + assertDoesNotThrow(() -> automationCompositionElementHandler.automationCompositionElementStateChange( + commonTestData.getAutomationCompositionId(), automationCompositionElementId1, + AutomationCompositionState.PASSIVE, AutomationCompositionOrderedState.RUNNING)); + + } + + @Test + void test_AutomationCompositionElementUpdate() throws PfModelException, IOException, ServiceException, + ExecutionException, InterruptedException { + doNothing().when(automationCompositionElementHandler).checkPodStatus(any(), any(), any(), anyInt(), anyInt()); + UUID elementId1 = UUID.randomUUID(); + AutomationCompositionElement element = new AutomationCompositionElement(); + element.setId(elementId1); + element.setDefinition(new ToscaConceptIdentifier(KEY_NAME, "1.0.1")); + element.setOrderedState(AutomationCompositionOrderedState.PASSIVE); + + Map nodeTemplatesMap = + toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates(); + automationCompositionElementHandler.automationCompositionElementUpdate( + commonTestData.getAutomationCompositionId(), element, + nodeTemplatesMap.get(K8S_AUTOMATION_COMPOSITION_ELEMENT)); + + assertThat(automationCompositionElementHandler.getChartMap()).hasSize(1).containsKey(elementId1); + + doThrow(new ServiceException("Error installing the chart")).when(chartService).installChart(Mockito.any()); + + UUID elementId2 = UUID.randomUUID(); + element.setId(elementId2); + automationCompositionElementHandler.automationCompositionElementUpdate( + commonTestData.getAutomationCompositionId(), element, + nodeTemplatesMap.get(K8S_AUTOMATION_COMPOSITION_ELEMENT)); + + assertThat(automationCompositionElementHandler.getChartMap().containsKey(elementId2)).isFalse(); + } + + @Test + void test_handleStatistics() throws PfModelException { + UUID elementId1 = UUID.randomUUID(); + automationCompositionElementHandler.getChartMap().put(elementId1, charts.get(0)); + when(participantIntermediaryApi.getAutomationCompositionElement(elementId1)) + .thenReturn(new AutomationCompositionElement()); + assertDoesNotThrow(() -> automationCompositionElementHandler.handleStatistics(elementId1)); + } + + @Test + void test_checkPodStatus() throws ExecutionException, InterruptedException { + doReturn(result).when(executor).submit(any(Runnable.class), any()); + doReturn("Done").when(result).get(); + doReturn(true).when(result).isDone(); + var chartInfo = charts.get(0); + ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier(); + AutomationCompositionElement element = new AutomationCompositionElement(); + assertDoesNotThrow( + () -> automationCompositionElementHandler.checkPodStatus(controlLoopId, element.getId(), chartInfo, + 1, 1)); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/HelmClientTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/HelmClientTest.java new file mode 100644 index 000000000..7f1943c97 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/HelmClientTest.java @@ -0,0 +1,158 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.kubernetes.helm; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartList; +import org.onap.policy.clamp.acm.participant.kubernetes.models.HelmRepository; +import org.onap.policy.clamp.acm.participant.kubernetes.service.ChartStore; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.util.FileSystemUtils; + + +@ExtendWith(SpringExtension.class) +class HelmClientTest { + + private static final Coder CODER = new StandardCoder(); + private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; + private static List charts; + + @InjectMocks + @Spy + private HelmClient helmClient = new HelmClient(); + + @Mock + ChartStore chartStore; + + @Mock + HelmRepository repo; + + private static MockedStatic mockedClient; + + @BeforeAll + static void init() throws CoderException { + charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); + //Mock static method for bash command execution + mockedClient = mockStatic(HelmClient.class); + } + + @AfterAll + public static void close() throws IOException { + mockedClient.close(); + FileSystemUtils.deleteRecursively(Path.of("target/tmp")); + } + + @Test + void test_installChart() throws IOException { + mockedClient.when(() -> HelmClient.executeCommand(any())) + .thenReturn("success"); + doReturn(new File("/target/tmp/override.yaml")).when(chartStore) + .getOverrideFile(any()); + var chartinfo = charts.get(0); + + assertDoesNotThrow(() -> helmClient.installChart(chartinfo)); + chartinfo.setNamespace(""); + assertDoesNotThrow(() -> helmClient.installChart(chartinfo)); + + mockedClient.when(() -> HelmClient.executeCommand(any())) + .thenReturn(new String()); + assertDoesNotThrow(() -> helmClient.installChart(chartinfo)); + + } + + @Test + void test_addRepository() throws IOException { + mockedClient.when(() -> HelmClient.executeCommand(any())) + .thenReturn(new String()); + when(repo.getRepoName()).thenReturn("RepoName"); + assertDoesNotThrow(() -> helmClient.addRepository(repo)); + + mockedClient.when(() -> HelmClient.executeCommand(any())) + .thenReturn("failed"); + assertDoesNotThrow(() -> helmClient.addRepository(repo)); + } + + @Test + void test_findChartRepository() throws IOException, ServiceException { + String tmpPath = "target/tmp/dummyChart/1.0/"; + mockedClient.when(() -> HelmClient.executeCommand(Mockito.any())) + .thenReturn("nginx-stable/nginx-ingress\t0.9.3\t1.11.3" + + " \tNGINX Ingress Controller"); + String configuredRepo = helmClient.findChartRepository(charts.get(1)); + assertThat(configuredRepo).isEqualTo("nginx-stable"); + + File tmpFile = new File(tmpPath + charts.get(1).getChartId().getName()); + tmpFile.mkdirs(); + doReturn(Path.of(tmpPath)).when(chartStore).getAppPath(charts.get(1).getChartId()); + + doReturn(null).when(helmClient).verifyConfiguredRepo(charts.get(1)); + + String localRepoName = helmClient.findChartRepository(charts.get(1)); + assertNotNull(localRepoName); + assertThat(localRepoName).endsWith(charts.get(0).getChartId().getVersion()); + } + + @Test + void test_uninstallChart() throws ServiceException { + helmClient.uninstallChart(charts.get(0)); + mockedClient.when(() -> HelmClient.executeCommand(any())).thenThrow(new ServiceException("error in execution")); + + assertThatThrownBy(() -> helmClient.uninstallChart(charts.get(0))) + .isInstanceOf(ServiceException.class); + } + + @Test + void test_verifyConfiguredRepoForInvalidChart() throws IOException, ServiceException { + mockedClient.when(() -> HelmClient.executeCommand(Mockito.any())) + .thenReturn(""); + String configuredRepo = helmClient.verifyConfiguredRepo(charts.get(1)); + assertNull(configuredRepo); + } + +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidatorTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidatorTest.java new file mode 100644 index 000000000..89b077044 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/helm/PodStatusValidatorTest.java @@ -0,0 +1,107 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.kubernetes.helm; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mockStatic; + +import java.io.File; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.MockedStatic; +import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.acm.participant.kubernetes.handler.AutomationCompositionElementHandler; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartList; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +class PodStatusValidatorTest { + + + private static final Coder CODER = new StandardCoder(); + private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; + private static List charts; + private static int timeout = 60; + private static int statusCheckInterval = 30; + + + @InjectMocks + private static PodStatusValidator podStatusValidator; + + private static MockedStatic mockedClient; + + + @BeforeAll + static void init() throws CoderException { + charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); + mockedClient = mockStatic(HelmClient.class); + podStatusValidator = new PodStatusValidator(charts.get(0), timeout, statusCheckInterval); + } + + @AfterEach + void clearPodStatusMap() { + AutomationCompositionElementHandler.getPodStatusMap().clear(); + } + + @AfterAll + public static void close() { + mockedClient.close(); + } + + + @Test + void test_RunningPodState() { + String runningPod = "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\r\nHelloWorld-54777df9f8-qpzqr\t1/1\tRunning\t0\t9h"; + mockedClient.when(() -> HelmClient.executeCommand(any())) + .thenReturn(runningPod); + assertDoesNotThrow(() -> podStatusValidator.run()); + assertThat(AutomationCompositionElementHandler.getPodStatusMap()).hasSize(1); + assertThat(AutomationCompositionElementHandler.getPodStatusMap()).containsKey(charts.get(0).getReleaseName()); + assertThat(AutomationCompositionElementHandler.getPodStatusMap()) + .containsValue(Map.of("HelloWorld-54777df9f8-qpzqr", "Running")); + } + + + @Test + void test_InvalidPodState() { + String invalidPod = "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\nhellofromdocker-54777df9f8-qpzqr\t1/1\tInit\t0\t9h"; + mockedClient.when(() -> HelmClient.executeCommand(any())) + .thenReturn(invalidPod); + assertThatThrownBy(() -> podStatusValidator.run()) + .isInstanceOf(ServiceException.class).hasMessage("Error verifying the status of the pod. Exiting"); + assertThat(AutomationCompositionElementHandler.getPodStatusMap()).isEmpty(); + } + +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/CommonTestData.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/CommonTestData.java new file mode 100644 index 000000000..13f8edc15 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/CommonTestData.java @@ -0,0 +1,161 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.kubernetes.parameters; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import org.onap.policy.common.endpoints.parameters.TopicParameters; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +public class CommonTestData { + + public static final String PARTICIPANT_GROUP_NAME = "AutomationCompositionParticipantGroup"; + public static final String DESCRIPTION = "Participant description"; + public static final long TIME_INTERVAL = 2000; + public static final List TOPIC_PARAMS = Arrays.asList(getTopicParams()); + public static final Coder CODER = new StandardCoder(); + + + /** + * Get ParticipantK8sParameters. + * + * @return ParticipantK8sParameters + */ + public ParticipantK8sParameters getParticipantK8sParameters() { + try { + return CODER.convert(getParticipantK8sParametersMap(PARTICIPANT_GROUP_NAME), + ParticipantK8sParameters.class); + } catch (final CoderException e) { + throw new RuntimeException("cannot create ParticipantK8sParameters from map", e); + } + } + + /** + * Returns a property map for a ParticipantK8sParameters map for test cases. + * + * @param name name of the parameters + * + * @return a property map suitable for constructing an object + */ + public Map getParticipantK8sParametersMap(final String name) { + final Map map = new TreeMap<>(); + + map.put("name", name); + map.put("intermediaryParameters", getIntermediaryParametersMap(false)); + map.put("localChartDirectory", getLocalChartDir()); + map.put("infoFileName", getInfoFileName()); + return map; + } + + + /** + * Returns string value of local chart Directory. + * @return a string value + */ + public String getLocalChartDir() { + return "/var/helm-manager/local-charts"; + } + + /** + * Returns string value of Info file name. + * @return string value + */ + public String getInfoFileName() { + return "CHART-INFO.json"; + } + + + + /** + * Returns a property map for a intermediaryParameters map for test cases. + * + * @param isEmpty boolean value to represent that object created should be empty or not + * @return a property map suitable for constructing an object + */ + public Map getIntermediaryParametersMap(final boolean isEmpty) { + final Map map = new TreeMap<>(); + if (!isEmpty) { + map.put("name", "Participant parameters"); + map.put("reportingTimeIntervalMs", TIME_INTERVAL); + map.put("description", DESCRIPTION); + map.put("participantId", getParticipantId()); + map.put("participantType", getParticipantId()); + map.put("clampAutomationCompositionTopics", getTopicParametersMap(false)); + } + + return map; + } + + /** + * Returns participantId for test cases. + * + * @return participant Id + */ + public static ToscaConceptIdentifier getParticipantId() { + final ToscaConceptIdentifier participantId = new ToscaConceptIdentifier(); + participantId.setName("K8sParticipant0"); + participantId.setVersion("1.0.0"); + return participantId; + } + + + /** + * Returns a property map for a TopicParameters map for test cases. + * + * @param isEmpty boolean value to represent that object created should be empty or not + * @return a property map suitable for constructing an object + */ + public Map getTopicParametersMap(final boolean isEmpty) { + final Map map = new TreeMap<>(); + if (!isEmpty) { + map.put("topicSources", TOPIC_PARAMS); + map.put("topicSinks", TOPIC_PARAMS); + } + return map; + } + + /** + * Returns topic parameters for test cases. + * + * @return topic parameters + */ + public static TopicParameters getTopicParams() { + final TopicParameters topicParams = new TopicParameters(); + topicParams.setTopic("POLICY-ACRUNTIME-PARTICIPANT"); + topicParams.setTopicCommInfrastructure("dmaap"); + topicParams.setServers(Arrays.asList("localhost")); + return topicParams; + } + + /** + * Get automation composition id. + * @return ToscaConceptIdentifier automationCompositionId + */ + public ToscaConceptIdentifier getAutomationCompositionId() { + return new ToscaConceptIdentifier("PMSHInstance0", "1.0.0"); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/ParticipantK8sParametersTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/ParticipantK8sParametersTest.java new file mode 100644 index 000000000..09ea74afe --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/ParticipantK8sParametersTest.java @@ -0,0 +1,89 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.kubernetes.parameters; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Set; +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.ValidatorFactory; +import org.junit.jupiter.api.Test; + +class ParticipantK8sParametersTest { + + private CommonTestData commonTestData = new CommonTestData(); + private ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); + + @Test + void testParticipantPolicyParameters() { + final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNullOrEmpty(); + } + + @Test + void testParticipantK8sParameters_NullTopicSinks() { + final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); + participantParameters.getIntermediaryParameters().getClampAutomationCompositionTopics().setTopicSinks(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } + + @Test + void testParticipantK8sParameters_NullTopicSources() { + final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); + participantParameters.getIntermediaryParameters().getClampAutomationCompositionTopics().setTopicSources(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } + + @Test + void testParticipantK8sParameters_BlankLocalChartDirParameter() { + final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); + participantParameters.setLocalChartDirectory(" "); + Set> violations = validatorFactory.getValidator() + .validate(participantParameters); + assertThat(violations.size()).isEqualTo(1); + } + + @Test + void testParticipantK8sParameters_BlankInfoFileParameter() { + final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); + participantParameters.setInfoFileName(""); + Set> violations = validatorFactory.getValidator() + .validate(participantParameters); + assertThat(violations.size()).isEqualTo(1); + } + + @Test + void testNoIntermediaryParameters() { + final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); + participantParameters.setIntermediaryParameters(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } + + @Test + void testNoParticipantId() { + final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); + participantParameters.getIntermediaryParameters().setParticipantId(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } + +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/rest/ActuatorControllerTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/rest/ActuatorControllerTest.java new file mode 100644 index 000000000..8d05d2bf6 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/rest/ActuatorControllerTest.java @@ -0,0 +1,92 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.kubernetes.rest; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import javax.ws.rs.client.Invocation; +import javax.ws.rs.core.Response; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.onap.policy.clamp.acm.participant.kubernetes.utils.CommonActuatorController; +import org.springframework.boot.test.autoconfigure.actuate.metrics.AutoConfigureMetrics; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@AutoConfigureMetrics +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@TestPropertySource(locations = {"classpath:application_test.properties"}) +class ActuatorControllerTest extends CommonActuatorController { + + private static final String HEALTH_ENDPOINT = "health"; + private static final String METRICS_ENDPOINT = "metrics"; + private static final String PROMETHEUS_ENDPOINT = "prometheus"; + + @LocalServerPort + private int randomServerPort; + + @BeforeEach + public void setUpPort() { + super.setHttpPrefix(randomServerPort); + } + + @Test + void testGetHealth_Unauthorized() throws Exception { + assertUnauthorizedActGet(HEALTH_ENDPOINT); + } + + @Test + void testGetMetrics_Unauthorized() throws Exception { + assertUnauthorizedActGet(METRICS_ENDPOINT); + } + + @Test + void testGetPrometheus_Unauthorized() throws Exception { + assertUnauthorizedActGet(PROMETHEUS_ENDPOINT); + } + + @Test + void testGetHealth() throws Exception { + Invocation.Builder invocationBuilder = super.sendActRequest(HEALTH_ENDPOINT); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + } + + @Test + void testGetMetrics() throws Exception { + Invocation.Builder invocationBuilder = super.sendActRequest(METRICS_ENDPOINT); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + } + + @Test + void testGePrometheus() throws Exception { + Invocation.Builder invocationBuilder = super.sendActRequest(PROMETHEUS_ENDPOINT); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + } + +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/rest/ChartControllerTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/rest/ChartControllerTest.java new file mode 100644 index 000000000..73c5c98a1 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/rest/ChartControllerTest.java @@ -0,0 +1,249 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021-2022 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.kubernetes.rest; + +import static org.hamcrest.CoreMatchers.is; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.List; +import org.apache.commons.io.FileUtils; +import org.json.JSONObject; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.onap.policy.clamp.acm.participant.kubernetes.controller.ChartController; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartList; +import org.onap.policy.clamp.acm.participant.kubernetes.parameters.ParticipantK8sParameters; +import org.onap.policy.clamp.acm.participant.kubernetes.service.ChartService; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.RequestBuilder; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + + +@ExtendWith(SpringExtension.class) +@WebMvcTest(value = ChartController.class, properties = "chart.api.enabled=true") +@EnableConfigurationProperties(value = ParticipantK8sParameters.class) +class ChartControllerTest { + + private static final Coder CODER = new StandardCoder(); + private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; + private static List charts; + private static String RETRIEVE_CHART_URL = "/helm/charts"; + private static String INSTALL_CHART_URL = "/helm/install"; + private static String UNINSTALL_CHART_URL = "/helm/uninstall/"; + private static String ONBOARD_CHART_URL = "/helm/onboard/chart"; + private static String DELETE_CHART_URL = "/helm/chart"; + private static String CONFIGURE_REPO_URL = "/helm/repo"; + + @Autowired + private MockMvc mockMvc; + + @MockBean + private ChartService chartService; + + @Autowired + private WebApplicationContext context; + + /** + * Read input chart info json. + * @throws Exception incase of error. + */ + @BeforeAll + static void setupParams() throws CoderException { + charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); + } + + /** + * Mock service layer in Controller. + * @throws Exception incase of error. + */ + @BeforeEach + void mockServiceClass() { + when(chartService.getAllCharts()).thenReturn(charts); + when(chartService.getChart(charts.get(0).getChartId().getName(), charts.get(0).getChartId().getVersion())) + .thenReturn(charts.get(0)); + + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build(); + } + + /** + * Test endpoint for retrieving all charts. + * @throws Exception incase of error. + */ + @Test + void retrieveAllCharts() throws Exception { + RequestBuilder requestBuilder; + requestBuilder = MockMvcRequestBuilders.get(RETRIEVE_CHART_URL).accept(MediaType.APPLICATION_JSON_VALUE); + + mockMvc.perform(requestBuilder).andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.charts.[0].chartId.name", is("HelloWorld"))); + } + + /** + * Test endpoint for installing a chart. + * @throws Exception incase of error. + */ + @Test + void installChart() throws Exception { + RequestBuilder requestBuilder; + + //Mocking successful installation for void install method + doNothing().when(chartService).installChart(charts.get(0)); + + requestBuilder = MockMvcRequestBuilders.post(INSTALL_CHART_URL).accept(MediaType.APPLICATION_JSON_VALUE) + .content(getInstallationJson(charts.get(0).getChartId().getName(), charts.get(0).getChartId().getVersion())) + .contentType(MediaType.APPLICATION_JSON_VALUE); + + mockMvc.perform(requestBuilder).andExpect(status().isCreated()); + + //Install Invalid chart, expects HTTP status NOT_FOUND + requestBuilder = MockMvcRequestBuilders.post(INSTALL_CHART_URL).accept(MediaType.APPLICATION_JSON_VALUE) + .content(getInstallationJson("invalidName", "invalidVersion")) + .contentType(MediaType.APPLICATION_JSON_VALUE); + + mockMvc.perform(requestBuilder).andExpect(status().isNotFound()); + } + + /** + * Test endpoint for uninstalling a chart. + * @throws Exception incase of error. + */ + @Test + void uninstallChart() throws Exception { + RequestBuilder requestBuilder; + + //Mocking successful scenario for void uninstall method + doNothing().when(chartService).uninstallChart(charts.get(0)); + + requestBuilder = MockMvcRequestBuilders.delete(UNINSTALL_CHART_URL + charts.get(0) + .getChartId().getName() + "/" + charts.get(0).getChartId().getVersion()) + .accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE); + + mockMvc.perform(requestBuilder).andExpect(status().isNoContent()); + + //Invalid chart + requestBuilder = MockMvcRequestBuilders.delete(UNINSTALL_CHART_URL + "invalidName" + + "/" + "invalidVersion").accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE); + + mockMvc.perform(requestBuilder).andExpect(status().isNotFound()); + } + + /** + * Test endpoint for chart onboarding. + * @throws Exception incase of error. + */ + @Test + void onboardChart() throws Exception { + RequestBuilder requestBuilder; + MockMultipartFile chartFile = new MockMultipartFile("chart", "hello.tgz", + MediaType.TEXT_PLAIN_VALUE, "Dummy data".getBytes()); + + MockMultipartFile overrideFile = new MockMultipartFile("values", "values.yaml", + MediaType.TEXT_PLAIN_VALUE, "Dummy data".getBytes()); + + //Mocking successful scenario for void uninstall method + when(chartService.saveChart(charts.get(0), chartFile, null)).thenReturn(charts.get(0)); + + requestBuilder = MockMvcRequestBuilders.multipart(ONBOARD_CHART_URL) + .file(chartFile).file(overrideFile).param("info", getChartInfoJson()); + + mockMvc.perform(requestBuilder).andExpect(status().isOk()); + } + + /** + * Test endpoint for deleting a chart. + * @throws Exception incase of error. + */ + @Test + void deleteChart() throws Exception { + RequestBuilder requestBuilder; + + //Mocking successful scenario for void uninstall method + doNothing().when(chartService).deleteChart(charts.get(0)); + + requestBuilder = MockMvcRequestBuilders.delete(DELETE_CHART_URL + "/" + charts.get(0) + .getChartId().getName() + "/" + charts.get(0).getChartId().getVersion()) + .accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE); + + mockMvc.perform(requestBuilder).andExpect(status().isNoContent()); + //Invalid chart + requestBuilder = MockMvcRequestBuilders.delete(UNINSTALL_CHART_URL + "invalidName" + + "/" + "invalidVersion").accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE); + + mockMvc.perform(requestBuilder).andExpect(status().isNotFound()); + + } + + /** + * Test endpoint for configuring a helm repository. + * @throws Exception in case of error. + */ + @Test + void testConfigureRepo() throws Exception { + RequestBuilder requestBuilder; + + requestBuilder = MockMvcRequestBuilders.post(CONFIGURE_REPO_URL).accept(MediaType.APPLICATION_JSON_VALUE) + .content(getInstallationJson(charts.get(0).getChartId().getName(), charts.get(0).getChartId().getVersion())) + .contentType(MediaType.APPLICATION_JSON_VALUE); + + mockMvc.perform(requestBuilder).andExpect(status().isCreated()); + + } + + + private String getInstallationJson(String name, String version) { + JSONObject jsonObj = new JSONObject(); + jsonObj.put("name", name); + jsonObj.put("version", version); + return jsonObj.toString(); + } + + private String getChartInfoJson() throws IOException { + return FileUtils.readFileToString(new File(CHART_INFO_YAML), StandardCharsets.UTF_8); + } + +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartServiceTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartServiceTest.java new file mode 100644 index 000000000..f5b6093d3 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartServiceTest.java @@ -0,0 +1,148 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.kubernetes.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.acm.participant.kubernetes.helm.HelmClient; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartList; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +class ChartServiceTest { + + private static final Coder CODER = new StandardCoder(); + private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; + private static List charts; + + @InjectMocks + @Spy + private ChartService chartService = new ChartService(); + + @Mock + private ChartStore chartStore; + + @Mock + private HelmClient helmClient; + + @BeforeAll + static void init() throws CoderException { + charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); + } + + @Test + void test_getAllCharts() { + assertThat(chartService.getAllCharts()).isEmpty(); + + doReturn(charts).when(chartStore).getAllCharts(); + Collection result = chartService.getAllCharts(); + assertNotNull(result); + assertThat(result).containsAll(charts); + } + + @Test + void test_getChart() { + assertNull(chartService.getChart("dummyName", "dummyversion")); + + doReturn(charts.get(0)).when(chartStore).getChart(any(), any()); + ChartInfo chart = chartService.getChart(charts.get(0).getChartId().getName(), + charts.get(0).getChartId().getVersion()); + assertNotNull(chart); + assertThat(chart.getNamespace()).isEqualTo(charts.get(0).getNamespace()); + } + + @Test + void test_saveChart() throws IOException, ServiceException { + doThrow(IOException.class).when(chartStore).saveChart(charts.get(0), null, null); + assertThatThrownBy(() -> chartService.saveChart(charts.get(0), null, null)) + .isInstanceOf(IOException.class); + + MockMultipartFile mockChartFile = new MockMultipartFile("chart", "dummy".getBytes()); + MockMultipartFile mockOverrideFile = new MockMultipartFile("override", "dummy".getBytes()); + + doReturn(charts.get(0)).when(chartStore).saveChart(any(), any(), any()); + + ChartInfo chart = chartService.saveChart(charts.get(0), mockChartFile, mockOverrideFile); + assertNotNull(chart); + assertThat(chart.getChartId().getName()).isEqualTo(charts.get(0).getChartId().getName()); + + } + + @Test + void test_installChart() throws IOException, ServiceException { + assertDoesNotThrow(() -> chartService.installChart(charts.get(0))); + doThrow(ServiceException.class).when(helmClient).installChart(any()); + assertThatThrownBy(() -> chartService.installChart(charts.get(0))).isInstanceOf(ServiceException.class); + + doReturn("dummyRepoName").when(chartService).findChartRepo(any()); + doNothing().when(helmClient).installChart(any()); + chartService.installChart(charts.get(1)); + assertEquals("dummyRepoName", charts.get(1).getRepository().getRepoName()); + + ChartInfo testChart = charts.get(1); + testChart.setRepository(null); + doReturn(null).when(chartService).findChartRepo(any()); + chartService.installChart(charts.get(1)); + } + + @Test + void test_UninstallChart() throws ServiceException { + assertDoesNotThrow(() -> chartService.uninstallChart(charts.get(0))); + doThrow(ServiceException.class).when(helmClient).uninstallChart(any()); + assertThatThrownBy(() -> chartService.uninstallChart(charts.get(0))).isInstanceOf(ServiceException.class); + } + + @Test + void test_findChartRepo() throws IOException, ServiceException { + assertDoesNotThrow(() -> chartService.findChartRepo(charts.get(0))); + doReturn("dummyRepoName").when(helmClient).findChartRepository(any()); + assertEquals("dummyRepoName", chartService.findChartRepo(charts.get(1))); + + doThrow(ServiceException.class).when(helmClient).findChartRepository(any()); + assertThatThrownBy(() -> chartService.findChartRepo(charts.get(0))).isInstanceOf(ServiceException.class); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartStoreTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartStoreTest.java new file mode 100644 index 000000000..180861bae --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/service/ChartStoreTest.java @@ -0,0 +1,175 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.kubernetes.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +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.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; +import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartList; +import org.onap.policy.clamp.acm.participant.kubernetes.parameters.ParticipantK8sParameters; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.util.FileSystemUtils; + + +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +class ChartStoreTest { + + private static final Coder CODER = new StandardCoder(); + private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; + private static List charts; + + @Mock + private ParticipantK8sParameters parameters; + + private ChartStore chartStore; + + + @BeforeAll + static void init() throws CoderException { + charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); + } + + //Overriding the local chart dir parameter to a temp folder under target for testing java FILE IO operations. + @BeforeEach + void setup() { + Mockito.doReturn("target/tmp/").when(parameters).getLocalChartDirectory(); + Mockito.doReturn("info.json").when(parameters).getInfoFileName(); + chartStore = new ChartStore(parameters); + } + + //Clean up the 'tmp' dir after each test case. + @AfterEach + void cleanUp() throws IOException { + FileSystemUtils.deleteRecursively(Path.of(parameters.getLocalChartDirectory())); + chartStore.getLocalChartMap().clear(); + } + + @Test + void test_getHelmChartFile() { + File file = chartStore.getHelmChartFile(charts.get(0)); + assertNotNull(file); + assertThat(file.getPath()).endsWith(charts.get(0).getChartId().getName()); + } + + @Test + void test_getOverrideFile() { + File file = chartStore.getOverrideFile(charts.get(0)); + assertNotNull(file); + assertThat(file.getPath()).endsWith("values.yaml"); + } + + @Test + void test_saveChart() throws IOException, ServiceException { + MockMultipartFile mockChartFile = new MockMultipartFile("chart", "dummy".getBytes()); + MockMultipartFile mockOverrideFile = new MockMultipartFile("override", "dummy".getBytes()); + ChartInfo testChart = charts.get(0); + testChart.setChartId(new ToscaConceptIdentifier("testChart", "1.0.0")); + ChartInfo result = chartStore.saveChart(charts.get(0), mockChartFile, mockOverrideFile); + + assertThat(result.getChartId().getName()).isEqualTo("testChart"); + assertThat(chartStore.getLocalChartMap()).hasSize(1); + + assertThatThrownBy(() -> chartStore.saveChart(charts.get(0), mockChartFile, mockOverrideFile)) + .isInstanceOf(ServiceException.class); + } + + + @Test + void test_getChart() { + assertNull(chartStore.getChart(charts.get(0).getChartId().getName(), charts.get(0).getChartId().getVersion())); + chartStore.getLocalChartMap().put(charts.get(0).getChartId().getName() + "_" + charts.get(0).getChartId() + .getVersion(), charts.get(0)); + ChartInfo chart = chartStore.getChart(charts.get(0).getChartId().getName(), + charts.get(0).getChartId().getVersion()); + assertThat(chart.getChartId().getName()).isEqualTo(charts.get(0).getChartId().getName()); + } + + @Test + void test_getAllChart() { + // When the chart store is empty before adding any charts + assertThat(chartStore.getAllCharts()).isEmpty(); + + for (ChartInfo chart : charts) { + chartStore.getLocalChartMap().put(chart.getChartId().getName() + "_" + chart.getChartId().getVersion(), + chart); + } + List retrievedChartList = chartStore.getAllCharts(); + assertThat(retrievedChartList).isNotEmpty(); + assertThat(retrievedChartList.size()).isEqualTo(charts.size()); + } + + @Test + void test_deleteChart() { + chartStore.getLocalChartMap().put(charts.get(0).getChartId().getName() + "_" + charts.get(0).getChartId() + .getVersion(), charts.get(0)); + assertThat(chartStore.getLocalChartMap()).hasSize(1); + chartStore.deleteChart(charts.get(0)); + assertThat(chartStore.getLocalChartMap()).isEmpty(); + } + + @Test + void test_getAppPath() { + Path path = chartStore.getAppPath(charts.get(0).getChartId()); + assertNotNull(path); + assertThat(path.toString()).endsWith(charts.get(0).getChartId().getVersion()); + assertThat(path.toString()).startsWith("target"); + } + + @Test + void test_chartSoreInstantiationWithExistingChartFiles() throws IOException, ServiceException { + MockMultipartFile mockChartFile = new MockMultipartFile("HelmChartFile", "dummyData".getBytes()); + MockMultipartFile mockOverrideFile = new MockMultipartFile("overrideFile.yaml", "dummyData".getBytes()); + ChartInfo testChart = charts.get(0); + testChart.setChartId(new ToscaConceptIdentifier("dummyChart", "1.0.0")); + + //Creating a dummy chart in local dir. + chartStore.saveChart(charts.get(0), mockChartFile, mockOverrideFile); + + //Instantiating a new chartStore object with pre available chart in local. + ChartStore chartStore2 = new ChartStore(parameters); + assertThat(chartStore2.getLocalChartMap()).hasSize(1).containsKey("dummyChart_" + charts.get(0).getChartId() + .getVersion()); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/utils/CommonActuatorController.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/utils/CommonActuatorController.java new file mode 100644 index 000000000..e5a5be9fa --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/utils/CommonActuatorController.java @@ -0,0 +1,114 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.kubernetes.utils; + +import static org.junit.Assert.assertEquals; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.glassfish.jersey.client.ClientProperties; +import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; +import org.onap.policy.common.gson.GsonMessageBodyHandler; +import org.onap.policy.common.utils.network.NetworkUtil; + +/** + * Class to perform Rest unit tests. + * + */ +public class CommonActuatorController { + + public static final String SELF = NetworkUtil.getHostname(); + public static final String CONTEXT_PATH = "onap/policy/clamp/acm/k8sparticipant"; + public static final String ACTUATOR_ENDPOINT = CONTEXT_PATH + "/actuator/"; + + private static String httpPrefix; + + /** + * Sends a request to an actuator endpoint. + * + * @param endpoint the target endpoint + * @return a request builder + * @throws Exception if an error occurs + */ + protected Invocation.Builder sendActRequest(final String endpoint) throws Exception { + return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + endpoint, true); + } + + /** + * Sends a request to an actuator endpoint, without any authorization header. + * + * @param endpoint the target endpoint + * @return a request builder + * @throws Exception if an error occurs + */ + protected Invocation.Builder sendNoAuthActRequest(final String endpoint) throws Exception { + return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + endpoint, false); + } + + /** + * Sends a request to a fully qualified endpoint. + * + * @param fullyQualifiedEndpoint the fully qualified target endpoint + * @param includeAuth if authorization header should be included + * @return a request builder + * @throws Exception if an error occurs + */ + protected Invocation.Builder sendFqeRequest(final String fullyQualifiedEndpoint, boolean includeAuth) + throws Exception { + final Client client = ClientBuilder.newBuilder().build(); + + client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true"); + client.register(GsonMessageBodyHandler.class); + + if (includeAuth) { + client.register(HttpAuthenticationFeature.basic("participantUser", "zb!XztG34")); + } + + final WebTarget webTarget = client.target(fullyQualifiedEndpoint); + + return webTarget.request(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN); + } + + /** + * Assert that GET call to actuator endpoint is Unauthorized. + * + * @param endPoint the endpoint + * @throws Exception if an error occurs + */ + protected void assertUnauthorizedActGet(final String endPoint) throws Exception { + Response rawresp = sendNoAuthActRequest(endPoint).buildGet().invoke(); + assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus()); + } + + /** + * Set Up httpPrefix. + * + * @param port the port + */ + protected void setHttpPrefix(int port) { + httpPrefix = "http://" + SELF + ":" + port + "/"; + } + +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/utils/TestUtils.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/utils/TestUtils.java new file mode 100644 index 000000000..8f4969a9b --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/utils/TestUtils.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.kubernetes.utils; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.onap.policy.common.utils.coder.YamlJsonTranslator; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class TestUtils { + + private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator(); + private static final String TOSCA_TEMPLATE_YAML = "src/test/resources/servicetemplates/KubernetesHelm.yaml"; + + public static ToscaServiceTemplate testAutomationCompositionRead() { + return testAutomationCompositionYamlSerialization(TOSCA_TEMPLATE_YAML); + } + + private static ToscaServiceTemplate testAutomationCompositionYamlSerialization( + String automationCompositionFilePath) { + String automationCompositionString = ResourceUtils.getResourceAsString(automationCompositionFilePath); + ToscaServiceTemplate serviceTemplate = + yamlTranslator.fromYaml(automationCompositionString, ToscaServiceTemplate.class); + return serviceTemplate; + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandlerTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandlerTest.java deleted file mode 100644 index 805404b90..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandlerTest.java +++ /dev/null @@ -1,180 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.kubernetes.handler; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.when; - -import java.io.File; -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.Spy; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartList; -import org.onap.policy.clamp.controlloop.participant.kubernetes.parameters.CommonTestData; -import org.onap.policy.clamp.controlloop.participant.kubernetes.service.ChartService; -import org.onap.policy.clamp.controlloop.participant.kubernetes.utils.TestUtils; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; -import org.springframework.test.context.junit.jupiter.SpringExtension; - - -@ExtendWith(SpringExtension.class) -class ControlLoopElementHandlerTest { - - private static final Coder CODER = new StandardCoder(); - private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; - private static final String KEY_NAME = "org.onap.domain.database.HelloWorld_K8SMicroserviceControlLoopElement"; - private static List charts; - private static ToscaServiceTemplate toscaServiceTemplate; - private static final String K8S_CONTROL_LOOP_ELEMENT = - "org.onap.domain.database.PMSH_K8SMicroserviceControlLoopElement"; - private CommonTestData commonTestData = new CommonTestData(); - - @InjectMocks - @Spy - private ControlLoopElementHandler controlLoopElementHandler = new ControlLoopElementHandler(); - - @Mock - private ChartService chartService; - - @Mock - private ParticipantIntermediaryApi participantIntermediaryApi; - - @Mock - private ExecutorService executor; - - @Mock - private Future result; - - @BeforeAll - static void init() throws CoderException { - charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); - toscaServiceTemplate = TestUtils.testControlLoopRead(); - } - - - @Test - void test_ControlLoopElementStateChange() throws ServiceException { - UUID controlLoopElementId1 = UUID.randomUUID(); - UUID controlLoopElementId2 = UUID.randomUUID(); - - controlLoopElementHandler.getChartMap().put(controlLoopElementId1, charts.get(0)); - controlLoopElementHandler.getChartMap().put(controlLoopElementId2, charts.get(1)); - - doNothing().when(chartService).uninstallChart(charts.get(0)); - - controlLoopElementHandler.controlLoopElementStateChange(commonTestData.getControlLoopId(), - controlLoopElementId1, ControlLoopState.PASSIVE, ControlLoopOrderedState.UNINITIALISED); - - doThrow(new ServiceException("Error uninstalling the chart")).when(chartService) - .uninstallChart(charts.get(0)); - - assertDoesNotThrow(() -> controlLoopElementHandler - .controlLoopElementStateChange(commonTestData.getControlLoopId(), controlLoopElementId1, - ControlLoopState.PASSIVE, ControlLoopOrderedState.PASSIVE)); - - assertDoesNotThrow(() -> controlLoopElementHandler - .controlLoopElementStateChange(commonTestData.getControlLoopId(), controlLoopElementId1, - ControlLoopState.PASSIVE, ControlLoopOrderedState.UNINITIALISED)); - - assertDoesNotThrow(() -> controlLoopElementHandler - .controlLoopElementStateChange(commonTestData.getControlLoopId(), controlLoopElementId1, - ControlLoopState.PASSIVE, ControlLoopOrderedState.RUNNING)); - - } - - @Test - void test_ControlLoopElementUpdate() throws PfModelException, IOException, ServiceException, - ExecutionException, InterruptedException { - doNothing().when(controlLoopElementHandler).checkPodStatus(any(), any(), any(), anyInt(), anyInt()); - UUID elementId1 = UUID.randomUUID(); - ControlLoopElement element = new ControlLoopElement(); - element.setId(elementId1); - element.setDefinition(new ToscaConceptIdentifier(KEY_NAME, "1.0.1")); - element.setOrderedState(ControlLoopOrderedState.PASSIVE); - - Map nodeTemplatesMap = - toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates(); - controlLoopElementHandler.controlLoopElementUpdate(commonTestData.getControlLoopId(), element, - nodeTemplatesMap.get(K8S_CONTROL_LOOP_ELEMENT)); - - assertThat(controlLoopElementHandler.getChartMap()).hasSize(1).containsKey(elementId1); - - doThrow(new ServiceException("Error installing the chart")).when(chartService) - .installChart(Mockito.any()); - - UUID elementId2 = UUID.randomUUID(); - element.setId(elementId2); - controlLoopElementHandler.controlLoopElementUpdate(commonTestData.getControlLoopId(), element, - nodeTemplatesMap.get(K8S_CONTROL_LOOP_ELEMENT)); - - assertThat(controlLoopElementHandler.getChartMap().containsKey(elementId2)).isFalse(); - } - - @Test - void test_handleStatistics() throws PfModelException { - UUID elementId1 = UUID.randomUUID(); - controlLoopElementHandler.getChartMap().put(elementId1, charts.get(0)); - when(participantIntermediaryApi.getControlLoopElement(elementId1)).thenReturn(new ControlLoopElement()); - assertDoesNotThrow(() -> controlLoopElementHandler.handleStatistics(elementId1)); - } - - @Test - void test_checkPodStatus() throws ExecutionException, InterruptedException { - doReturn(result).when(executor).submit(any(Runnable.class), any()); - doReturn("Done").when(result).get(); - doReturn(true).when(result).isDone(); - var chartInfo = charts.get(0); - ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier(); - ControlLoopElement element = new ControlLoopElement(); - assertDoesNotThrow(() -> controlLoopElementHandler.checkPodStatus(controlLoopId, element.getId(), chartInfo, - 1, 1)); - } -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClientTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClientTest.java deleted file mode 100644 index 335dbcb21..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClientTest.java +++ /dev/null @@ -1,158 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.kubernetes.helm; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.Assert.assertNull; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mockStatic; -import static org.mockito.Mockito.when; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Path; -import java.util.List; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.Spy; -import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartList; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.HelmRepository; -import org.onap.policy.clamp.controlloop.participant.kubernetes.service.ChartStore; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.springframework.test.context.junit.jupiter.SpringExtension; -import org.springframework.util.FileSystemUtils; - - -@ExtendWith(SpringExtension.class) -class HelmClientTest { - - private static final Coder CODER = new StandardCoder(); - private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; - private static List charts; - - @InjectMocks - @Spy - private HelmClient helmClient = new HelmClient(); - - @Mock - ChartStore chartStore; - - @Mock - HelmRepository repo; - - private static MockedStatic mockedClient; - - @BeforeAll - static void init() throws CoderException { - charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); - //Mock static method for bash command execution - mockedClient = mockStatic(HelmClient.class); - } - - @AfterAll - public static void close() throws IOException { - mockedClient.close(); - FileSystemUtils.deleteRecursively(Path.of("target/tmp")); - } - - @Test - void test_installChart() throws IOException { - mockedClient.when(() -> HelmClient.executeCommand(any())) - .thenReturn("success"); - doReturn(new File("/target/tmp/override.yaml")).when(chartStore) - .getOverrideFile(any()); - var chartinfo = charts.get(0); - - assertDoesNotThrow(() -> helmClient.installChart(chartinfo)); - chartinfo.setNamespace(""); - assertDoesNotThrow(() -> helmClient.installChart(chartinfo)); - - mockedClient.when(() -> HelmClient.executeCommand(any())) - .thenReturn(new String()); - assertDoesNotThrow(() -> helmClient.installChart(chartinfo)); - - } - - @Test - void test_addRepository() throws IOException { - mockedClient.when(() -> HelmClient.executeCommand(any())) - .thenReturn(new String()); - when(repo.getRepoName()).thenReturn("RepoName"); - assertDoesNotThrow(() -> helmClient.addRepository(repo)); - - mockedClient.when(() -> HelmClient.executeCommand(any())) - .thenReturn("failed"); - assertDoesNotThrow(() -> helmClient.addRepository(repo)); - } - - @Test - void test_findChartRepository() throws IOException, ServiceException { - String tmpPath = "target/tmp/dummyChart/1.0/"; - mockedClient.when(() -> HelmClient.executeCommand(Mockito.any())) - .thenReturn("nginx-stable/nginx-ingress\t0.9.3\t1.11.3" - + " \tNGINX Ingress Controller"); - String configuredRepo = helmClient.findChartRepository(charts.get(1)); - assertThat(configuredRepo).isEqualTo("nginx-stable"); - - File tmpFile = new File(tmpPath + charts.get(1).getChartId().getName()); - tmpFile.mkdirs(); - doReturn(Path.of(tmpPath)).when(chartStore).getAppPath(charts.get(1).getChartId()); - - doReturn(null).when(helmClient).verifyConfiguredRepo(charts.get(1)); - - String localRepoName = helmClient.findChartRepository(charts.get(1)); - assertNotNull(localRepoName); - assertThat(localRepoName).endsWith(charts.get(0).getChartId().getVersion()); - } - - @Test - void test_uninstallChart() throws ServiceException { - helmClient.uninstallChart(charts.get(0)); - mockedClient.when(() -> HelmClient.executeCommand(any())).thenThrow(new ServiceException("error in execution")); - - assertThatThrownBy(() -> helmClient.uninstallChart(charts.get(0))) - .isInstanceOf(ServiceException.class); - } - - @Test - void test_verifyConfiguredRepoForInvalidChart() throws IOException, ServiceException { - mockedClient.when(() -> HelmClient.executeCommand(Mockito.any())) - .thenReturn(""); - String configuredRepo = helmClient.verifyConfiguredRepo(charts.get(1)); - assertNull(configuredRepo); - } - -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/PodStatusValidatorTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/PodStatusValidatorTest.java deleted file mode 100644 index 18c32d474..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/PodStatusValidatorTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.kubernetes.helm; - - - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mockStatic; - -import java.io.File; -import java.util.List; -import java.util.Map; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.MockedStatic; -import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; -import org.onap.policy.clamp.controlloop.participant.kubernetes.handler.ControlLoopElementHandler; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartList; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@ExtendWith(SpringExtension.class) -class PodStatusValidatorTest { - - - private static final Coder CODER = new StandardCoder(); - private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; - private static List charts; - private static int timeout = 60; - private static int statusCheckInterval = 30; - - - @InjectMocks - private static PodStatusValidator podStatusValidator; - - private static MockedStatic mockedClient; - - - @BeforeAll - static void init() throws CoderException { - charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); - mockedClient = mockStatic(HelmClient.class); - podStatusValidator = new PodStatusValidator(charts.get(0), timeout, statusCheckInterval); - } - - @AfterEach - void clearPodStatusMap() { - ControlLoopElementHandler.getPodStatusMap().clear(); - } - - @AfterAll - public static void close() { - mockedClient.close(); - } - - - @Test - void test_RunningPodState() { - String runningPod = "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\r\nHelloWorld-54777df9f8-qpzqr\t1/1\tRunning\t0\t9h"; - mockedClient.when(() -> HelmClient.executeCommand(any())) - .thenReturn(runningPod); - assertDoesNotThrow(() -> podStatusValidator.run()); - assertThat(ControlLoopElementHandler.getPodStatusMap()).hasSize(1); - assertThat(ControlLoopElementHandler.getPodStatusMap()).containsKey(charts.get(0).getReleaseName()); - assertThat(ControlLoopElementHandler.getPodStatusMap()) - .containsValue(Map.of("HelloWorld-54777df9f8-qpzqr", "Running")); - } - - - @Test - void test_InvalidPodState() { - String invalidPod = "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\nhellofromdocker-54777df9f8-qpzqr\t1/1\tInit\t0\t9h"; - mockedClient.when(() -> HelmClient.executeCommand(any())) - .thenReturn(invalidPod); - assertThatThrownBy(() -> podStatusValidator.run()) - .isInstanceOf(ServiceException.class).hasMessage("Error verifying the status of the pod. Exiting"); - assertThat(ControlLoopElementHandler.getPodStatusMap()).isEmpty(); - } - -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/CommonTestData.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/CommonTestData.java deleted file mode 100644 index f6ec401b8..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/CommonTestData.java +++ /dev/null @@ -1,161 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.kubernetes.parameters; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import org.onap.policy.common.endpoints.parameters.TopicParameters; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; - -public class CommonTestData { - - public static final String PARTICIPANT_GROUP_NAME = "ControlLoopParticipantGroup"; - public static final String DESCRIPTION = "Participant description"; - public static final long TIME_INTERVAL = 2000; - public static final List TOPIC_PARAMS = Arrays.asList(getTopicParams()); - public static final Coder CODER = new StandardCoder(); - - - /** - * Get ParticipantK8sParameters. - * - * @return ParticipantK8sParameters - */ - public ParticipantK8sParameters getParticipantK8sParameters() { - try { - return CODER.convert(getParticipantK8sParametersMap(PARTICIPANT_GROUP_NAME), - ParticipantK8sParameters.class); - } catch (final CoderException e) { - throw new RuntimeException("cannot create ParticipantK8sParameters from map", e); - } - } - - /** - * Returns a property map for a ParticipantK8sParameters map for test cases. - * - * @param name name of the parameters - * - * @return a property map suitable for constructing an object - */ - public Map getParticipantK8sParametersMap(final String name) { - final Map map = new TreeMap<>(); - - map.put("name", name); - map.put("intermediaryParameters", getIntermediaryParametersMap(false)); - map.put("localChartDirectory", getLocalChartDir()); - map.put("infoFileName", getInfoFileName()); - return map; - } - - - /** - * Returns string value of local chart Directory. - * @return a string value - */ - public String getLocalChartDir() { - return "/var/helm-manager/local-charts"; - } - - /** - * Returns string value of Info file name. - * @return string value - */ - public String getInfoFileName() { - return "CHART-INFO.json"; - } - - - - /** - * Returns a property map for a intermediaryParameters map for test cases. - * - * @param isEmpty boolean value to represent that object created should be empty or not - * @return a property map suitable for constructing an object - */ - public Map getIntermediaryParametersMap(final boolean isEmpty) { - final Map map = new TreeMap<>(); - if (!isEmpty) { - map.put("name", "Participant parameters"); - map.put("reportingTimeIntervalMs", TIME_INTERVAL); - map.put("description", DESCRIPTION); - map.put("participantId", getParticipantId()); - map.put("participantType", getParticipantId()); - map.put("clampControlLoopTopics", getTopicParametersMap(false)); - } - - return map; - } - - /** - * Returns participantId for test cases. - * - * @return participant Id - */ - public static ToscaConceptIdentifier getParticipantId() { - final ToscaConceptIdentifier participantId = new ToscaConceptIdentifier(); - participantId.setName("K8sParticipant0"); - participantId.setVersion("1.0.0"); - return participantId; - } - - - /** - * Returns a property map for a TopicParameters map for test cases. - * - * @param isEmpty boolean value to represent that object created should be empty or not - * @return a property map suitable for constructing an object - */ - public Map getTopicParametersMap(final boolean isEmpty) { - final Map map = new TreeMap<>(); - if (!isEmpty) { - map.put("topicSources", TOPIC_PARAMS); - map.put("topicSinks", TOPIC_PARAMS); - } - return map; - } - - /** - * Returns topic parameters for test cases. - * - * @return topic parameters - */ - public static TopicParameters getTopicParams() { - final TopicParameters topicParams = new TopicParameters(); - topicParams.setTopic("POLICY-CLRUNTIME-PARTICIPANT"); - topicParams.setTopicCommInfrastructure("dmaap"); - topicParams.setServers(Arrays.asList("localhost")); - return topicParams; - } - - /** - * Get controlloop id. - * @return ToscaConceptIdentifier controlLoopId - */ - public ToscaConceptIdentifier getControlLoopId() { - return new ToscaConceptIdentifier("PMSHInstance0", "1.0.0"); - } -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParametersTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParametersTest.java deleted file mode 100644 index f22fc711e..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParametersTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.kubernetes.parameters; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.ValidatorFactory; -import org.junit.jupiter.api.Test; - -class ParticipantK8sParametersTest { - - private CommonTestData commonTestData = new CommonTestData(); - private ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); - - @Test - void testParticipantPolicyParameters() { - final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isNullOrEmpty(); - } - - @Test - void testParticipantK8sParameters_NullTopicSinks() { - final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); - participantParameters.getIntermediaryParameters().getClampControlLoopTopics().setTopicSinks(null); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); - } - - @Test - void testParticipantK8sParameters_NullTopicSources() { - final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); - participantParameters.getIntermediaryParameters().getClampControlLoopTopics().setTopicSources(null); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); - } - - @Test - void testParticipantK8sParameters_BlankLocalChartDirParameter() { - final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); - participantParameters.setLocalChartDirectory(" "); - Set> violations = validatorFactory.getValidator() - .validate(participantParameters); - assertThat(violations.size()).isEqualTo(1); - } - - @Test - void testParticipantK8sParameters_BlankInfoFileParameter() { - final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); - participantParameters.setInfoFileName(""); - Set> violations = validatorFactory.getValidator() - .validate(participantParameters); - assertThat(violations.size()).isEqualTo(1); - } - - @Test - void testNoIntermediaryParameters() { - final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); - participantParameters.setIntermediaryParameters(null); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); - } - - @Test - void testNoParticipantId() { - final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); - participantParameters.getIntermediaryParameters().setParticipantId(null); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); - } - -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/rest/ActuatorControllerTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/rest/ActuatorControllerTest.java deleted file mode 100644 index 1442e9f1f..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/rest/ActuatorControllerTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.kubernetes.rest; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import javax.ws.rs.client.Invocation; -import javax.ws.rs.core.Response; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.onap.policy.clamp.controlloop.participant.kubernetes.utils.CommonActuatorController; -import org.springframework.boot.test.autoconfigure.actuate.metrics.AutoConfigureMetrics; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@AutoConfigureMetrics -@ExtendWith(SpringExtension.class) -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -@TestPropertySource(locations = {"classpath:application_test.properties"}) -class ActuatorControllerTest extends CommonActuatorController { - - private static final String HEALTH_ENDPOINT = "health"; - private static final String METRICS_ENDPOINT = "metrics"; - private static final String PROMETHEUS_ENDPOINT = "prometheus"; - - @LocalServerPort - private int randomServerPort; - - @BeforeEach - public void setUpPort() { - super.setHttpPrefix(randomServerPort); - } - - @Test - void testGetHealth_Unauthorized() throws Exception { - assertUnauthorizedActGet(HEALTH_ENDPOINT); - } - - @Test - void testGetMetrics_Unauthorized() throws Exception { - assertUnauthorizedActGet(METRICS_ENDPOINT); - } - - @Test - void testGetPrometheus_Unauthorized() throws Exception { - assertUnauthorizedActGet(PROMETHEUS_ENDPOINT); - } - - @Test - void testGetHealth() throws Exception { - Invocation.Builder invocationBuilder = super.sendActRequest(HEALTH_ENDPOINT); - Response rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); - } - - @Test - void testGetMetrics() throws Exception { - Invocation.Builder invocationBuilder = super.sendActRequest(METRICS_ENDPOINT); - Response rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); - } - - @Test - void testGePrometheus() throws Exception { - Invocation.Builder invocationBuilder = super.sendActRequest(PROMETHEUS_ENDPOINT); - Response rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); - } - -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/rest/ChartControllerTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/rest/ChartControllerTest.java deleted file mode 100644 index 8048b19ce..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/rest/ChartControllerTest.java +++ /dev/null @@ -1,249 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.kubernetes.rest; - -import static org.hamcrest.CoreMatchers.is; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.List; -import org.apache.commons.io.FileUtils; -import org.json.JSONObject; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.onap.policy.clamp.controlloop.participant.kubernetes.controller.ChartController; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartList; -import org.onap.policy.clamp.controlloop.participant.kubernetes.parameters.ParticipantK8sParameters; -import org.onap.policy.clamp.controlloop.participant.kubernetes.service.ChartService; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.mock.web.MockMultipartFile; -import org.springframework.test.context.junit.jupiter.SpringExtension; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.RequestBuilder; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; - - -@ExtendWith(SpringExtension.class) -@WebMvcTest(value = ChartController.class, properties = "chart.api.enabled=true") -@EnableConfigurationProperties(value = ParticipantK8sParameters.class) -class ChartControllerTest { - - private static final Coder CODER = new StandardCoder(); - private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; - private static List charts; - private static String RETRIEVE_CHART_URL = "/helm/charts"; - private static String INSTALL_CHART_URL = "/helm/install"; - private static String UNINSTALL_CHART_URL = "/helm/uninstall/"; - private static String ONBOARD_CHART_URL = "/helm/onboard/chart"; - private static String DELETE_CHART_URL = "/helm/chart"; - private static String CONFIGURE_REPO_URL = "/helm/repo"; - - @Autowired - private MockMvc mockMvc; - - @MockBean - private ChartService chartService; - - @Autowired - private WebApplicationContext context; - - /** - * Read input chart info json. - * @throws Exception incase of error. - */ - @BeforeAll - static void setupParams() throws CoderException { - charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); - } - - /** - * Mock service layer in Controller. - * @throws Exception incase of error. - */ - @BeforeEach - void mockServiceClass() { - when(chartService.getAllCharts()).thenReturn(charts); - when(chartService.getChart(charts.get(0).getChartId().getName(), charts.get(0).getChartId().getVersion())) - .thenReturn(charts.get(0)); - - this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build(); - } - - /** - * Test endpoint for retrieving all charts. - * @throws Exception incase of error. - */ - @Test - void retrieveAllCharts() throws Exception { - RequestBuilder requestBuilder; - requestBuilder = MockMvcRequestBuilders.get(RETRIEVE_CHART_URL).accept(MediaType.APPLICATION_JSON_VALUE); - - mockMvc.perform(requestBuilder).andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.charts.[0].chartId.name", is("HelloWorld"))); - } - - /** - * Test endpoint for installing a chart. - * @throws Exception incase of error. - */ - @Test - void installChart() throws Exception { - RequestBuilder requestBuilder; - - //Mocking successful installation for void install method - doNothing().when(chartService).installChart(charts.get(0)); - - requestBuilder = MockMvcRequestBuilders.post(INSTALL_CHART_URL).accept(MediaType.APPLICATION_JSON_VALUE) - .content(getInstallationJson(charts.get(0).getChartId().getName(), charts.get(0).getChartId().getVersion())) - .contentType(MediaType.APPLICATION_JSON_VALUE); - - mockMvc.perform(requestBuilder).andExpect(status().isCreated()); - - //Install Invalid chart, expects HTTP status NOT_FOUND - requestBuilder = MockMvcRequestBuilders.post(INSTALL_CHART_URL).accept(MediaType.APPLICATION_JSON_VALUE) - .content(getInstallationJson("invalidName", "invalidVersion")) - .contentType(MediaType.APPLICATION_JSON_VALUE); - - mockMvc.perform(requestBuilder).andExpect(status().isNotFound()); - } - - /** - * Test endpoint for uninstalling a chart. - * @throws Exception incase of error. - */ - @Test - void uninstallChart() throws Exception { - RequestBuilder requestBuilder; - - //Mocking successful scenario for void uninstall method - doNothing().when(chartService).uninstallChart(charts.get(0)); - - requestBuilder = MockMvcRequestBuilders.delete(UNINSTALL_CHART_URL + charts.get(0) - .getChartId().getName() + "/" + charts.get(0).getChartId().getVersion()) - .accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE); - - mockMvc.perform(requestBuilder).andExpect(status().isNoContent()); - - //Invalid chart - requestBuilder = MockMvcRequestBuilders.delete(UNINSTALL_CHART_URL + "invalidName" - + "/" + "invalidVersion").accept(MediaType.APPLICATION_JSON_VALUE) - .contentType(MediaType.APPLICATION_JSON_VALUE); - - mockMvc.perform(requestBuilder).andExpect(status().isNotFound()); - } - - /** - * Test endpoint for chart onboarding. - * @throws Exception incase of error. - */ - @Test - void onboardChart() throws Exception { - RequestBuilder requestBuilder; - MockMultipartFile chartFile = new MockMultipartFile("chart", "hello.tgz", - MediaType.TEXT_PLAIN_VALUE, "Dummy data".getBytes()); - - MockMultipartFile overrideFile = new MockMultipartFile("values", "values.yaml", - MediaType.TEXT_PLAIN_VALUE, "Dummy data".getBytes()); - - //Mocking successful scenario for void uninstall method - when(chartService.saveChart(charts.get(0), chartFile, null)).thenReturn(charts.get(0)); - - requestBuilder = MockMvcRequestBuilders.multipart(ONBOARD_CHART_URL) - .file(chartFile).file(overrideFile).param("info", getChartInfoJson()); - - mockMvc.perform(requestBuilder).andExpect(status().isOk()); - } - - /** - * Test endpoint for deleting a chart. - * @throws Exception incase of error. - */ - @Test - void deleteChart() throws Exception { - RequestBuilder requestBuilder; - - //Mocking successful scenario for void uninstall method - doNothing().when(chartService).deleteChart(charts.get(0)); - - requestBuilder = MockMvcRequestBuilders.delete(DELETE_CHART_URL + "/" + charts.get(0) - .getChartId().getName() + "/" + charts.get(0).getChartId().getVersion()) - .accept(MediaType.APPLICATION_JSON_VALUE) - .contentType(MediaType.APPLICATION_JSON_VALUE); - - mockMvc.perform(requestBuilder).andExpect(status().isNoContent()); - //Invalid chart - requestBuilder = MockMvcRequestBuilders.delete(UNINSTALL_CHART_URL + "invalidName" - + "/" + "invalidVersion").accept(MediaType.APPLICATION_JSON_VALUE) - .contentType(MediaType.APPLICATION_JSON_VALUE); - - mockMvc.perform(requestBuilder).andExpect(status().isNotFound()); - - } - - /** - * Test endpoint for configuring a helm repository. - * @throws Exception in case of error. - */ - @Test - void testConfigureRepo() throws Exception { - RequestBuilder requestBuilder; - - requestBuilder = MockMvcRequestBuilders.post(CONFIGURE_REPO_URL).accept(MediaType.APPLICATION_JSON_VALUE) - .content(getInstallationJson(charts.get(0).getChartId().getName(), charts.get(0).getChartId().getVersion())) - .contentType(MediaType.APPLICATION_JSON_VALUE); - - mockMvc.perform(requestBuilder).andExpect(status().isCreated()); - - } - - - private String getInstallationJson(String name, String version) { - JSONObject jsonObj = new JSONObject(); - jsonObj.put("name", name); - jsonObj.put("version", version); - return jsonObj.toString(); - } - - private String getChartInfoJson() throws IOException { - return FileUtils.readFileToString(new File(CHART_INFO_YAML), StandardCharsets.UTF_8); - } - -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartServiceTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartServiceTest.java deleted file mode 100644 index f1c8d19df..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartServiceTest.java +++ /dev/null @@ -1,148 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.kubernetes.service; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; - -import java.io.File; -import java.io.IOException; -import java.util.Collection; -import java.util.List; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Spy; -import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; -import org.onap.policy.clamp.controlloop.participant.kubernetes.helm.HelmClient; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartList; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.springframework.mock.web.MockMultipartFile; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@ExtendWith(SpringExtension.class) -class ChartServiceTest { - - private static final Coder CODER = new StandardCoder(); - private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; - private static List charts; - - @InjectMocks - @Spy - private ChartService chartService = new ChartService(); - - @Mock - private ChartStore chartStore; - - @Mock - private HelmClient helmClient; - - @BeforeAll - static void init() throws CoderException { - charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); - } - - @Test - void test_getAllCharts() { - assertThat(chartService.getAllCharts()).isEmpty(); - - doReturn(charts).when(chartStore).getAllCharts(); - Collection result = chartService.getAllCharts(); - assertNotNull(result); - assertThat(result).containsAll(charts); - } - - @Test - void test_getChart() { - assertNull(chartService.getChart("dummyName", "dummyversion")); - - doReturn(charts.get(0)).when(chartStore).getChart(any(), any()); - ChartInfo chart = chartService.getChart(charts.get(0).getChartId().getName(), - charts.get(0).getChartId().getVersion()); - assertNotNull(chart); - assertThat(chart.getNamespace()).isEqualTo(charts.get(0).getNamespace()); - } - - @Test - void test_saveChart() throws IOException, ServiceException { - doThrow(IOException.class).when(chartStore).saveChart(charts.get(0), null, null); - assertThatThrownBy(() -> chartService.saveChart(charts.get(0), null, null)) - .isInstanceOf(IOException.class); - - MockMultipartFile mockChartFile = new MockMultipartFile("chart", "dummy".getBytes()); - MockMultipartFile mockOverrideFile = new MockMultipartFile("override", "dummy".getBytes()); - - doReturn(charts.get(0)).when(chartStore).saveChart(any(), any(), any()); - - ChartInfo chart = chartService.saveChart(charts.get(0), mockChartFile, mockOverrideFile); - assertNotNull(chart); - assertThat(chart.getChartId().getName()).isEqualTo(charts.get(0).getChartId().getName()); - - } - - @Test - void test_installChart() throws IOException, ServiceException { - assertDoesNotThrow(() -> chartService.installChart(charts.get(0))); - doThrow(ServiceException.class).when(helmClient).installChart(any()); - assertThatThrownBy(() -> chartService.installChart(charts.get(0))).isInstanceOf(ServiceException.class); - - doReturn("dummyRepoName").when(chartService).findChartRepo(any()); - doNothing().when(helmClient).installChart(any()); - chartService.installChart(charts.get(1)); - assertEquals("dummyRepoName", charts.get(1).getRepository().getRepoName()); - - ChartInfo testChart = charts.get(1); - testChart.setRepository(null); - doReturn(null).when(chartService).findChartRepo(any()); - chartService.installChart(charts.get(1)); - } - - @Test - void test_UninstallChart() throws ServiceException { - assertDoesNotThrow(() -> chartService.uninstallChart(charts.get(0))); - doThrow(ServiceException.class).when(helmClient).uninstallChart(any()); - assertThatThrownBy(() -> chartService.uninstallChart(charts.get(0))).isInstanceOf(ServiceException.class); - } - - @Test - void test_findChartRepo() throws IOException, ServiceException { - assertDoesNotThrow(() -> chartService.findChartRepo(charts.get(0))); - doReturn("dummyRepoName").when(helmClient).findChartRepository(any()); - assertEquals("dummyRepoName", chartService.findChartRepo(charts.get(1))); - - doThrow(ServiceException.class).when(helmClient).findChartRepository(any()); - assertThatThrownBy(() -> chartService.findChartRepo(charts.get(0))).isInstanceOf(ServiceException.class); - } -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartStoreTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartStoreTest.java deleted file mode 100644 index 54f1cc528..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartStoreTest.java +++ /dev/null @@ -1,175 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.kubernetes.service; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.Assert.assertNull; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Path; -import java.util.List; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -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.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; -import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; -import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartList; -import org.onap.policy.clamp.controlloop.participant.kubernetes.parameters.ParticipantK8sParameters; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.springframework.mock.web.MockMultipartFile; -import org.springframework.util.FileSystemUtils; - - -@ExtendWith(MockitoExtension.class) -@MockitoSettings(strictness = Strictness.LENIENT) -class ChartStoreTest { - - private static final Coder CODER = new StandardCoder(); - private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; - private static List charts; - - @Mock - private ParticipantK8sParameters parameters; - - private ChartStore chartStore; - - - @BeforeAll - static void init() throws CoderException { - charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); - } - - //Overriding the local chart dir parameter to a temp folder under target for testing java FILE IO operations. - @BeforeEach - void setup() { - Mockito.doReturn("target/tmp/").when(parameters).getLocalChartDirectory(); - Mockito.doReturn("info.json").when(parameters).getInfoFileName(); - chartStore = new ChartStore(parameters); - } - - //Clean up the 'tmp' dir after each test case. - @AfterEach - void cleanUp() throws IOException { - FileSystemUtils.deleteRecursively(Path.of(parameters.getLocalChartDirectory())); - chartStore.getLocalChartMap().clear(); - } - - @Test - void test_getHelmChartFile() { - File file = chartStore.getHelmChartFile(charts.get(0)); - assertNotNull(file); - assertThat(file.getPath()).endsWith(charts.get(0).getChartId().getName()); - } - - @Test - void test_getOverrideFile() { - File file = chartStore.getOverrideFile(charts.get(0)); - assertNotNull(file); - assertThat(file.getPath()).endsWith("values.yaml"); - } - - @Test - void test_saveChart() throws IOException, ServiceException { - MockMultipartFile mockChartFile = new MockMultipartFile("chart", "dummy".getBytes()); - MockMultipartFile mockOverrideFile = new MockMultipartFile("override", "dummy".getBytes()); - ChartInfo testChart = charts.get(0); - testChart.setChartId(new ToscaConceptIdentifier("testChart", "1.0.0")); - ChartInfo result = chartStore.saveChart(charts.get(0), mockChartFile, mockOverrideFile); - - assertThat(result.getChartId().getName()).isEqualTo("testChart"); - assertThat(chartStore.getLocalChartMap()).hasSize(1); - - assertThatThrownBy(() -> chartStore.saveChart(charts.get(0), mockChartFile, mockOverrideFile)) - .isInstanceOf(ServiceException.class); - } - - - @Test - void test_getChart() { - assertNull(chartStore.getChart(charts.get(0).getChartId().getName(), charts.get(0).getChartId().getVersion())); - chartStore.getLocalChartMap().put(charts.get(0).getChartId().getName() + "_" + charts.get(0).getChartId() - .getVersion(), charts.get(0)); - ChartInfo chart = chartStore.getChart(charts.get(0).getChartId().getName(), - charts.get(0).getChartId().getVersion()); - assertThat(chart.getChartId().getName()).isEqualTo(charts.get(0).getChartId().getName()); - } - - @Test - void test_getAllChart() { - // When the chart store is empty before adding any charts - assertThat(chartStore.getAllCharts()).isEmpty(); - - for (ChartInfo chart : charts) { - chartStore.getLocalChartMap().put(chart.getChartId().getName() + "_" + chart.getChartId().getVersion(), - chart); - } - List retrievedChartList = chartStore.getAllCharts(); - assertThat(retrievedChartList).isNotEmpty(); - assertThat(retrievedChartList.size()).isEqualTo(charts.size()); - } - - @Test - void test_deleteChart() { - chartStore.getLocalChartMap().put(charts.get(0).getChartId().getName() + "_" + charts.get(0).getChartId() - .getVersion(), charts.get(0)); - assertThat(chartStore.getLocalChartMap()).hasSize(1); - chartStore.deleteChart(charts.get(0)); - assertThat(chartStore.getLocalChartMap()).isEmpty(); - } - - @Test - void test_getAppPath() { - Path path = chartStore.getAppPath(charts.get(0).getChartId()); - assertNotNull(path); - assertThat(path.toString()).endsWith(charts.get(0).getChartId().getVersion()); - assertThat(path.toString()).startsWith("target"); - } - - @Test - void test_chartSoreInstantiationWithExistingChartFiles() throws IOException, ServiceException { - MockMultipartFile mockChartFile = new MockMultipartFile("HelmChartFile", "dummyData".getBytes()); - MockMultipartFile mockOverrideFile = new MockMultipartFile("overrideFile.yaml", "dummyData".getBytes()); - ChartInfo testChart = charts.get(0); - testChart.setChartId(new ToscaConceptIdentifier("dummyChart", "1.0.0")); - - //Creating a dummy chart in local dir. - chartStore.saveChart(charts.get(0), mockChartFile, mockOverrideFile); - - //Instantiating a new chartStore object with pre available chart in local. - ChartStore chartStore2 = new ChartStore(parameters); - assertThat(chartStore2.getLocalChartMap()).hasSize(1).containsKey("dummyChart_" + charts.get(0).getChartId() - .getVersion()); - } -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/utils/CommonActuatorController.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/utils/CommonActuatorController.java deleted file mode 100644 index 35ffbb5e9..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/utils/CommonActuatorController.java +++ /dev/null @@ -1,114 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.kubernetes.utils; - -import static org.junit.Assert.assertEquals; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Invocation; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import org.glassfish.jersey.client.ClientProperties; -import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; -import org.onap.policy.common.gson.GsonMessageBodyHandler; -import org.onap.policy.common.utils.network.NetworkUtil; - -/** - * Class to perform Rest unit tests. - * - */ -public class CommonActuatorController { - - public static final String SELF = NetworkUtil.getHostname(); - public static final String CONTEXT_PATH = "onap/k8sparticipant"; - public static final String ACTUATOR_ENDPOINT = CONTEXT_PATH + "/actuator/"; - - private static String httpPrefix; - - /** - * Sends a request to an actuator endpoint. - * - * @param endpoint the target endpoint - * @return a request builder - * @throws Exception if an error occurs - */ - protected Invocation.Builder sendActRequest(final String endpoint) throws Exception { - return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + endpoint, true); - } - - /** - * Sends a request to an actuator endpoint, without any authorization header. - * - * @param endpoint the target endpoint - * @return a request builder - * @throws Exception if an error occurs - */ - protected Invocation.Builder sendNoAuthActRequest(final String endpoint) throws Exception { - return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + endpoint, false); - } - - /** - * Sends a request to a fully qualified endpoint. - * - * @param fullyQualifiedEndpoint the fully qualified target endpoint - * @param includeAuth if authorization header should be included - * @return a request builder - * @throws Exception if an error occurs - */ - protected Invocation.Builder sendFqeRequest(final String fullyQualifiedEndpoint, boolean includeAuth) - throws Exception { - final Client client = ClientBuilder.newBuilder().build(); - - client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true"); - client.register(GsonMessageBodyHandler.class); - - if (includeAuth) { - client.register(HttpAuthenticationFeature.basic("participantUser", "zb!XztG34")); - } - - final WebTarget webTarget = client.target(fullyQualifiedEndpoint); - - return webTarget.request(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN); - } - - /** - * Assert that GET call to actuator endpoint is Unauthorized. - * - * @param endPoint the endpoint - * @throws Exception if an error occurs - */ - protected void assertUnauthorizedActGet(final String endPoint) throws Exception { - Response rawresp = sendNoAuthActRequest(endPoint).buildGet().invoke(); - assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus()); - } - - /** - * Set Up httpPrefix. - * - * @param port the port - */ - protected void setHttpPrefix(int port) { - httpPrefix = "http://" + SELF + ":" + port + "/"; - } - -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/utils/TestUtils.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/utils/TestUtils.java deleted file mode 100644 index af514f8aa..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/utils/TestUtils.java +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.kubernetes.utils; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.onap.policy.common.utils.coder.YamlJsonTranslator; -import org.onap.policy.common.utils.resources.ResourceUtils; -import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public final class TestUtils { - - private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator(); - private static final String TOSCA_TEMPLATE_YAML = "src/test/resources/servicetemplates/KubernetesHelm.yaml"; - - - public static ToscaServiceTemplate testControlLoopRead() { - return testControlLoopYamlSerialization(TOSCA_TEMPLATE_YAML); - } - - - private static ToscaServiceTemplate testControlLoopYamlSerialization(String controlLoopFilePath) { - String controlLoopString = ResourceUtils.getResourceAsString(controlLoopFilePath); - ToscaServiceTemplate serviceTemplate = yamlTranslator.fromYaml(controlLoopString, ToscaServiceTemplate.class); - return serviceTemplate; - } -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/resources/application_test.properties b/participant/participant-impl/participant-impl-kubernetes/src/test/resources/application_test.properties index b5b209fd1..243512166 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/resources/application_test.properties +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/resources/application_test.properties @@ -1,24 +1,24 @@ spring.security.user.name=participantUser spring.security.user.password=zb!XztG34 -server.servlet.context-path=/onap/k8sparticipant +server.servlet.context-path=/onap/policy/clamp/acm/k8sparticipant server.error.path=/error server.http-port=8083 -participant.name=ControlLoopParticipant Kubernetes Test +participant.name=AutomationCompositionParticipant Kubernetes Test participant.intermediaryParameters.name=Participant parameters participant.intermediaryParameters.reportingTimeInterval=120000 participant.intermediaryParameters.description=Participant Description participant.intermediaryParameters.participantId.name=K8sParticipant0 participant.intermediaryParameters.participantId.version=1.0.0 -participant.intermediaryParameters.participantType.name=org.onap.k8s.controlloop.K8SControlLoopParticipant +participant.intermediaryParameters.participantType.name=org.onap.k8s.acm.K8SAutomationCompositionParticipant participant.intermediaryParameters.participantType.version=2.3.4 -participant.intermediaryParameters.clampControlLoopTopics.name=ControlLoop Topics -participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].topic=POLICY-CLRUNTIME-PARTICIPANT -participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].servers[0]=localhost -participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].topicCommInfrastructure=dmaap -participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].fetchTimeout=15000 -participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].topic=POLICY-CLRUNTIME-PARTICIPANT -participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].servers[0]=localhost -participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].topicCommInfrastructure=dmaap +participant.intermediaryParameters.clampAutomationCompositionTopics.name=AutomationComposition Topics +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSources[0].topic=POLICY-ACRUNTIME-PARTICIPANT +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSources[0].servers[0]=localhost +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSources[0].topicCommInfrastructure=dmaap +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSources[0].fetchTimeout=15000 +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSinks[0].topic=POLICY-ACRUNTIME-PARTICIPANT +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSinks[0].servers[0]=localhost +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSinks[0].topicCommInfrastructure=dmaap management.endpoints.web.exposure.include=health,metrics,prometheus diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/resources/servicetemplates/KubernetesHelm.yaml b/participant/participant-impl/participant-impl-kubernetes/src/test/resources/servicetemplates/KubernetesHelm.yaml index 7d594019a..f5eb6233f 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/resources/servicetemplates/KubernetesHelm.yaml +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/resources/servicetemplates/KubernetesHelm.yaml @@ -27,14 +27,14 @@ data_types: type: string required: true node_types: - org.onap.policy.clamp.controlloop.Participant: + org.onap.policy.clamp.acm.Participant: version: 1.0.1 derived_from: tosca.nodetypes.Root properties: provider: type: string requred: false - org.onap.policy.clamp.controlloop.ControlLoopElement: + org.onap.policy.clamp.acm.AutomationCompositionElement: version: 1.0.1 derived_from: tosca.nodetypes.Root properties: @@ -51,11 +51,11 @@ node_types: - greater-or-equal: 0 metadata: common: true - description: A value indicating the start phase in which this control loop element will be started, the - first start phase is zero. Control Loop Elements are started in their start_phase order and stopped - in reverse start phase order. Control Loop Elements with the same start phase are started and - stopped simultaneously - org.onap.policy.clamp.controlloop.ControlLoop: + description: A value indicating the start phase in which this automation composition element will be started, + the first start phase is zero. Automation Composition Elements are started in their start_phase + order and stopped in reverse start phase order. Automation Composition Elements with the same start + phase are started and stopped simultaneously + org.onap.policy.clamp.acm.AutomationComposition: version: 1.0.1 derived_from: tosca.nodetypes.Root properties: @@ -67,9 +67,9 @@ node_types: required: true entry_schema: type: onap.datatypes.ToscaConceptIdentifier - org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement: + org.onap.policy.clamp.acm.K8SMicroserviceAutomationCompositionElement: version: 1.0.1 - derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement + derived_from: org.onap.policy.clamp.acm.AutomationCompositionElement properties: chart: type: string @@ -89,24 +89,24 @@ node_types: requred: true topology_template: node_templates: - org.onap.k8s.controlloop.K8SControlLoopParticipant: + org.onap.k8s.acm.K8SAutomationCompositionParticipant: version: 2.3.4 - type: org.onap.policy.clamp.controlloop.Participant + type: org.onap.policy.clamp.acm.Participant type_version: 1.0.1 description: Participant for K8S properties: provider: ONAP - org.onap.domain.database.HelloWorld_K8SMicroserviceControlLoopElement: + org.onap.domain.database.HelloWorld_K8SMicroserviceAutomationCompositionElement: # Chart from any chart repository configured on helm client. version: 1.2.3 - type: org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement + type: org.onap.policy.clamp.acm.K8SMicroserviceAutomationCompositionElement type_version: 1.0.0 - description: Control loop element for the K8S microservice for Hello World + description: Automation composition element for the K8S microservice for Hello World properties: provider: ONAP participantType: - name: org.onap.k8s.controlloop.K8SControlLoopParticipant + name: org.onap.k8s.acm.K8SAutomationCompositionParticipant version: 2.3.4 startPhase: 2 uninitializedToPassiveTimeout: 180 @@ -119,16 +119,16 @@ topology_template: namespace: onap repository: chartMuseum - org.onap.domain.database.PMSH_K8SMicroserviceControlLoopElement: + org.onap.domain.database.PMSH_K8SMicroserviceAutomationCompositionElement: # Chart from local file system version: 1.2.3 - type: org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement + type: org.onap.policy.clamp.acm.K8SMicroserviceAutomationCompositionElement type_version: 1.0.0 - description: Control loop element for the K8S microservice for PMSH + description: Automation composition element for the K8S microservice for PMSH properties: provider: ONAP participantType: - name: org.onap.k8s.controlloop.K8SControlLoopParticipant + name: org.onap.k8s.acm.K8SAutomationCompositionParticipant version: 2.3.4 startPhase: 2 uninitializedToPassiveTimeout: 180 @@ -142,16 +142,16 @@ topology_template: overrideParams: global.masterPassword: test - org.onap.domain.database.Local_K8SMicroserviceControlLoopElement: + org.onap.domain.database.Local_K8SMicroserviceAutomationCompositionElement: # Chart installation without passing repository name version: 1.2.3 - type: org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement + type: org.onap.policy.clamp.acm.K8SMicroserviceAutomationCompositionElement type_version: 1.0.0 - description: Control loop element for the K8S microservice for local chart + description: Automation composition element for the K8S microservice for local chart properties: provider: ONAP participantType: - name: org.onap.k8s.controlloop.K8SControlLoopParticipant + name: org.onap.k8s.acm.K8SAutomationCompositionParticipant version: 2.3.4 startPhase: 2 uninitializedToPassiveTimeout: 180 @@ -163,17 +163,17 @@ topology_template: releaseName: nginxms namespace: onap - org.onap.domain.sample.GenericK8s_ControlLoopDefinition: + org.onap.domain.sample.GenericK8s_AutomationCompositionDefinition: version: 1.2.3 - type: org.onap.policy.clamp.controlloop.ControlLoop + type: org.onap.policy.clamp.acm.AutomationComposition type_version: 1.0.0 - description: Control loop for Hello World + description: Automation composition for Hello World properties: provider: ONAP elements: - - name: org.onap.domain.database.HelloWorld_K8SMicroserviceControlLoopElement + - name: org.onap.domain.database.HelloWorld_K8SMicroserviceAutomationCompositionElement version: 1.2.3 - - name: org.onap.domain.database.PMSH_K8SMicroserviceControlLoopElement + - name: org.onap.domain.database.PMSH_K8SMicroserviceAutomationCompositionElement version: 1.2.3 - - name: org.onap.domain.database.Local_K8SMicroserviceControlLoopElement + - name: org.onap.domain.database.Local_K8SMicroserviceAutomationCompositionElement version: 1.2.3 diff --git a/participant/participant-impl/participant-impl-policy/pom.xml b/participant/participant-impl/participant-impl-policy/pom.xml index fce29acae..052e959dc 100644 --- a/participant/participant-impl/participant-impl-policy/pom.xml +++ b/participant/participant-impl/participant-impl-policy/pom.xml @@ -30,7 +30,7 @@ policy-clamp-participant-impl-policy ${project.artifactId} - Policy participant, that allows Policy to partake in control loops + Policy participant, that allows Policy to partake in automation compositions diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/PolicyParticipantApplication.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/PolicyParticipantApplication.java new file mode 100644 index 000000000..0ba2aa2ea --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/PolicyParticipantApplication.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.policy; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.ConfigurationPropertiesScan; +import org.springframework.context.annotation.ComponentScan; + +/** + * Starter. + * + */ +@SpringBootApplication +@ComponentScan({ + "org.onap.policy.clamp.acm.participant.policy", + "org.onap.policy.clamp.acm.participant.intermediary" +}) +@ConfigurationPropertiesScan("org.onap.policy.clamp.acm.participant.policy.main.parameters") +public class PolicyParticipantApplication { + + public static void main(String[] args) { + SpringApplication.run(PolicyParticipantApplication.class, args); + } +} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/client/AbstractHttpClient.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/client/AbstractHttpClient.java new file mode 100644 index 000000000..4920d6550 --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/client/AbstractHttpClient.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.policy.client; + +import java.io.Closeable; +import java.io.IOException; +import java.util.Collections; +import java.util.Map; +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException; +import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; +import org.onap.policy.common.endpoints.http.client.HttpClient; +import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractHttpClient implements Closeable { + + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractHttpClient.class); + private final HttpClient httpclient; + + /** + * Constructor. + * + * @param policyParticipantParameters the parameters for the policy participant + * @throws AutomationCompositionRuntimeException on client start errors + */ + protected AbstractHttpClient(BusTopicParams policyParticipantParameters) { + try { + httpclient = HttpClientFactoryInstance.getClientFactory().build(policyParticipantParameters); + } catch (final Exception e) { + throw new AutomationCompositionRuntimeException(Status.INTERNAL_SERVER_ERROR, " Client failed to start", e); + } + } + + protected Response executePost(String path, final Entity entity) { + var response = httpclient.post(path, entity, Map.of(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON, + HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)); + if (response.getStatus() / 100 != 2) { + LOGGER.error("Invocation of path {} failed for entity {}. Response status: {}, Response status info: {}", + path, entity, response.getStatus(), response.getStatusInfo()); + } + return response; + } + + protected Response executeDelete(String path) { + return httpclient.delete(path, Collections.emptyMap()); + } + + @Override + public void close() throws IOException { + httpclient.shutdown(); + } +} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/client/PolicyApiHttpClient.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/client/PolicyApiHttpClient.java new file mode 100644 index 000000000..a86576eed --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/client/PolicyApiHttpClient.java @@ -0,0 +1,87 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.policy.client; + +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.onap.policy.clamp.acm.participant.policy.main.parameters.ParticipantPolicyParameters; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.springframework.stereotype.Component; + +@Component +public class PolicyApiHttpClient extends AbstractHttpClient { + + private static final String POLICY_URI = "/policy/api/v1/"; + + /** + * Constructor. + * + * @param parameters the policy participant parameters + */ + public PolicyApiHttpClient(ParticipantPolicyParameters parameters) { + super(parameters.getPolicyApiParameters()); + } + + /** + * Create Policy Types. + * + * @param toscaServiceTemplate the whole ToscaServiceTemplate + * @return Response + * @throws PfModelException on errors creating the policy type + */ + public Response createPolicyType(ToscaServiceTemplate toscaServiceTemplate) throws PfModelException { + return executePost(POLICY_URI + "policytypes", Entity.entity(toscaServiceTemplate, MediaType.APPLICATION_JSON)); + } + + /** + * Create Policies. + * + * @param toscaServiceTemplate the whole ToscaServiceTemplate + * @return Response + */ + public Response createPolicy(final ToscaServiceTemplate toscaServiceTemplate) { + return executePost(POLICY_URI + "policies", Entity.entity(toscaServiceTemplate, MediaType.APPLICATION_JSON)); + } + + /** + * Delete Policies. + * + * @param policyName the name of the policy to be deleted + * @param policyVersion the version of the policy to be deleted + * @return Response + */ + public Response deletePolicy(final String policyName, final String policyVersion) { + return executeDelete(POLICY_URI + "policies/" + policyName + "/versions/" + policyVersion); + } + + /** + * Delete Policy types. + * + * @param policyTypeName the name of the policy to be deleted + * @param policyTypeVersion the version of the policy to be deleted + * @return Response + */ + public Response deletePolicyType(final String policyTypeName, final String policyTypeVersion) { + return executeDelete(POLICY_URI + "policytypes/" + policyTypeName + "/versions/" + policyTypeVersion); + } +} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/client/PolicyPapHttpClient.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/client/PolicyPapHttpClient.java new file mode 100644 index 000000000..584170ae4 --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/client/PolicyPapHttpClient.java @@ -0,0 +1,85 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.policy.client; + +import java.util.LinkedList; +import java.util.List; +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.onap.policy.clamp.acm.participant.policy.main.parameters.ParticipantPolicyParameters; +import org.onap.policy.models.pdp.concepts.DeploymentGroup; +import org.onap.policy.models.pdp.concepts.DeploymentGroups; +import org.onap.policy.models.pdp.concepts.DeploymentSubGroup; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.springframework.stereotype.Component; + +@Component +public class PolicyPapHttpClient extends AbstractHttpClient { + + private static final String PAP_URI = "/policy/pap/v1/"; + private final String pdpGroup; + private final String pdpType; + + /** + * Constructor. + * + * @param parameters the policy participant parameters + */ + public PolicyPapHttpClient(ParticipantPolicyParameters parameters) { + super(parameters.getPolicyPapParameters()); + this.pdpGroup = parameters.getPdpGroup(); + this.pdpType = parameters.getPdpType(); + } + + /** + * Deploy or undeploy Policies. + * + * @param policyName the name of the policy to be deployed/undeployed + * @param policyVersion the version of the policy to be deployed/undeployed + * @param action the action to deploy/undeploy policy + * @return Response + */ + public Response handlePolicyDeployOrUndeploy(final String policyName, final String policyVersion, + final DeploymentSubGroup.Action action) { + + List policies = new LinkedList(); + policies.add(new ToscaConceptIdentifier(policyName, policyVersion)); + + DeploymentSubGroup subGroup = new DeploymentSubGroup(); + subGroup.setPolicies(policies); + subGroup.setPdpType(pdpType); + subGroup.setAction(action); + + DeploymentGroup group = new DeploymentGroup(); + List subGroups = new LinkedList(); + subGroups.add(subGroup); + group.setDeploymentSubgroups(subGroups); + group.setName(pdpGroup); + + DeploymentGroups groups = new DeploymentGroups(); + List groupsArr = new LinkedList(); + groupsArr.add(group); + groups.setGroups(groupsArr); + + return executePost(PAP_URI + "pdps/deployments/batch", Entity.entity(groups, MediaType.APPLICATION_JSON)); + } +} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/config/ParticipantConfig.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/config/ParticipantConfig.java new file mode 100644 index 000000000..7f9ad243d --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/config/ParticipantConfig.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.policy.config; + +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.acm.participant.policy.main.handler.AutomationCompositionElementHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ParticipantConfig { + + /** + * Register AutomationCompositionElementListener. + * + * @param intermediaryApi the ParticipantIntermediaryApi + * @param acElementHandler the Aotumation Composition Element Handler + */ + @Autowired + public void registerAutomationCompositionElementListener(ParticipantIntermediaryApi intermediaryApi, + AutomationCompositionElementHandler acElementHandler) { + intermediaryApi.registerAutomationCompositionElementListener(acElementHandler); + acElementHandler.setIntermediaryApi(intermediaryApi); + } +} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/config/SecurityConfig.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/config/SecurityConfig.java new file mode 100644 index 000000000..d7ce925e2 --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/config/SecurityConfig.java @@ -0,0 +1,45 @@ +/*- + * ========================LICENSE_START================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.policy.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Value("${security.enable-csrf:true}") + private boolean csrfEnabled = true; + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.authorizeRequests() + .antMatchers().authenticated() + .anyRequest().authenticated() + .and().httpBasic(); + // @formatter:on + + if (!csrfEnabled) { + http.csrf().disable(); + } + } +} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandler.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandler.java new file mode 100644 index 000000000..42d7526f8 --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandler.java @@ -0,0 +1,227 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021,2022 Nordix Foundation. + * ================================================================================ + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.policy.main.handler; + +import java.time.Instant; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; +import lombok.Setter; +import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener; +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.acm.participant.policy.client.PolicyApiHttpClient; +import org.onap.policy.clamp.acm.participant.policy.client.PolicyPapHttpClient; +import org.onap.policy.clamp.models.acm.concepts.AcElementStatistics; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.base.PfModelRuntimeException; +import org.onap.policy.models.pdp.concepts.DeploymentSubGroup; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * This class handles implementation of automationCompositionElement updates. + */ +@Component +public class AutomationCompositionElementHandler implements AutomationCompositionElementListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionElementHandler.class); + private final Map policyTypeMap = new LinkedHashMap<>(); + private final Map policyMap = new LinkedHashMap<>(); + + private final PolicyApiHttpClient apiHttpClient; + private final PolicyPapHttpClient papHttpClient; + + @Setter + private ParticipantIntermediaryApi intermediaryApi; + + /** + * constructor. + * + * @param apiHttpClient the Policy Api Http Client + * @param papHttpClient the Policy Pap Http Client + */ + public AutomationCompositionElementHandler(PolicyApiHttpClient apiHttpClient, PolicyPapHttpClient papHttpClient) { + this.papHttpClient = papHttpClient; + this.apiHttpClient = apiHttpClient; + } + + /** + * Callback method to handle a automation composition element state change. + * + * @param automationCompositionId the ID of the automation composition + * @param automationCompositionElementId the ID of the automation composition element + * @param currentState the current state of the automation composition element + * @param orderedState the state to which the automation composition element is changing to + */ + @Override + public void automationCompositionElementStateChange(ToscaConceptIdentifier automationCompositionId, + UUID automationCompositionElementId, + AutomationCompositionState currentState, + AutomationCompositionOrderedState orderedState) { + switch (orderedState) { + case UNINITIALISED: + try { + undeployPolicies(automationCompositionElementId); + deletePolicyData(automationCompositionId, automationCompositionElementId, orderedState); + intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, + automationCompositionElementId, orderedState, AutomationCompositionState.UNINITIALISED, + ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE); + } catch (PfModelRuntimeException e) { + LOGGER.debug("Undeploying/Deleting policy failed {}", automationCompositionElementId, e); + } + break; + case PASSIVE: + try { + undeployPolicies(automationCompositionElementId); + } catch (PfModelRuntimeException e) { + LOGGER.debug("Undeploying policies failed - no policies to undeploy {}", + automationCompositionElementId); + } + intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, + automationCompositionElementId, orderedState, AutomationCompositionState.PASSIVE, + ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE); + break; + case RUNNING: + LOGGER.info("Running state is not supported"); + break; + default: + LOGGER.debug("Unknown orderedstate {}", orderedState); + break; + } + } + + private void deletePolicyData(ToscaConceptIdentifier automationCompositionId, + UUID automationCompositionElementId, AutomationCompositionOrderedState newState) { + // Delete all policies of this automationComposition from policy framework + for (Entry policy : policyMap.entrySet()) { + apiHttpClient.deletePolicy(policy.getKey(), policy.getValue()); + } + policyMap.clear(); + // Delete all policy types of this automation composition from policy framework + for (Entry policyType : policyTypeMap.entrySet()) { + apiHttpClient.deletePolicyType(policyType.getKey(), policyType.getValue()); + } + policyTypeMap.clear(); + intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, + automationCompositionElementId, newState, AutomationCompositionState.UNINITIALISED, + ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE); + } + + private void deployPolicies(ToscaConceptIdentifier automationCompositionId, UUID automationCompositionElementId, + AutomationCompositionOrderedState newState) { + // Deploy all policies of this automationComposition from Policy Framework + if (!policyMap.entrySet().isEmpty()) { + for (Entry policy : policyMap.entrySet()) { + papHttpClient.handlePolicyDeployOrUndeploy(policy.getKey(), policy.getValue(), + DeploymentSubGroup.Action.POST); + } + LOGGER.debug("Policies deployed to {} successfully", automationCompositionElementId); + } else { + LOGGER.debug("No policies to deploy to {}", automationCompositionElementId); + } + intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, + automationCompositionElementId, newState, AutomationCompositionState.PASSIVE, + ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE); + } + + private void undeployPolicies(UUID automationCompositionElementId) { + // Undeploy all policies of this automation composition from Policy Framework + if (!policyMap.entrySet().isEmpty()) { + for (Entry policy : policyMap.entrySet()) { + papHttpClient.handlePolicyDeployOrUndeploy(policy.getKey(), policy.getValue(), + DeploymentSubGroup.Action.DELETE); + } + LOGGER.debug("Undeployed policies from {} successfully", automationCompositionElementId); + } else { + LOGGER.debug("No policies are deployed to {}", automationCompositionElementId); + } + } + + /** + * Callback method to handle an update on a automation composition element. + * + * @param element the information on the automation composition element + * @param acElementDefinition toscaNodeTemplate + * @throws PfModelException in case of an exception + */ + @Override + public void automationCompositionElementUpdate(ToscaConceptIdentifier automationCompositionId, + AutomationCompositionElement element, + ToscaNodeTemplate acElementDefinition) + throws PfModelException { + intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(), + element.getOrderedState(), + AutomationCompositionState.PASSIVE, ParticipantMessageType.AUTOMATION_COMPOSITION_UPDATE); + ToscaServiceTemplate automationCompositionDefinition = element.getToscaServiceTemplateFragment(); + if (automationCompositionDefinition.getToscaTopologyTemplate() != null) { + if (automationCompositionDefinition.getPolicyTypes() != null) { + for (ToscaPolicyType policyType : automationCompositionDefinition.getPolicyTypes().values()) { + policyTypeMap.put(policyType.getName(), policyType.getVersion()); + } + LOGGER.debug("Found Policy Types in automation composition definition: {} , Creating Policy Types", + automationCompositionDefinition.getName()); + apiHttpClient.createPolicyType(automationCompositionDefinition); + } + if (automationCompositionDefinition.getToscaTopologyTemplate().getPolicies() != null) { + for (Map gotPolicyMap : automationCompositionDefinition.getToscaTopologyTemplate() + .getPolicies()) { + for (ToscaPolicy policy : gotPolicyMap.values()) { + policyMap.put(policy.getName(), policy.getVersion()); + } + } + LOGGER.debug("Found Policies in automation composition definition: {} , Creating Policies", + automationCompositionDefinition.getName()); + apiHttpClient.createPolicy(automationCompositionDefinition); + } + } + deployPolicies(automationCompositionId, element.getId(), element.getOrderedState()); + } + + /** + * Handle automationCompositionElement statistics. + * + * @param automationCompositionElementId automation composition element id + */ + @Override + public void handleStatistics(UUID automationCompositionElementId) { + var acElement = intermediaryApi.getAutomationCompositionElement(automationCompositionElementId); + if (acElement != null) { + var acElementStatistics = new AcElementStatistics(); + acElementStatistics.setState(acElement.getState()); + acElementStatistics.setTimeStamp(Instant.now()); + intermediaryApi.updateAutomationCompositionElementStatistics(automationCompositionElementId, + acElementStatistics); + } + } +} \ No newline at end of file diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/main/parameters/ParticipantPolicyParameters.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/main/parameters/ParticipantPolicyParameters.java new file mode 100644 index 000000000..a57198126 --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/main/parameters/ParticipantPolicyParameters.java @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.policy.main.parameters; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; +import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantIntermediaryParameters; +import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantParameters; +import org.onap.policy.common.endpoints.parameters.RestClientParameters; +import org.onap.policy.common.parameters.validation.ParameterGroupConstraint; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.validation.annotation.Validated; + +/** + * Class to hold all parameters needed for the policy participant. + * + */ +@Validated +@Getter +@Setter +@ConfigurationProperties(prefix = "participant") +public class ParticipantPolicyParameters implements ParticipantParameters { + + @NotNull + @Valid + private ParticipantIntermediaryParameters intermediaryParameters; + + @NotNull + @ParameterGroupConstraint + private RestClientParameters policyApiParameters; + + @NotNull + @ParameterGroupConstraint + private RestClientParameters policyPapParameters; + + @NotBlank + private String pdpGroup; + + @NotBlank + private String pdpType; +} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/PolicyParticipantApplication.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/PolicyParticipantApplication.java deleted file mode 100644 index 4869b7c2f..000000000 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/PolicyParticipantApplication.java +++ /dev/null @@ -1,42 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.policy; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.context.properties.ConfigurationPropertiesScan; -import org.springframework.context.annotation.ComponentScan; - -/** - * Starter. - * - */ -@SpringBootApplication -@ComponentScan({ - "org.onap.policy.clamp.controlloop.participant.policy", - "org.onap.policy.clamp.controlloop.participant.intermediary"}) -@ConfigurationPropertiesScan("org.onap.policy.clamp.controlloop.participant.policy.main.parameters") -public class PolicyParticipantApplication { - - public static void main(String[] args) { - SpringApplication.run(PolicyParticipantApplication.class, args); - } -} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/client/AbstractHttpClient.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/client/AbstractHttpClient.java deleted file mode 100644 index 2579585e5..000000000 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/client/AbstractHttpClient.java +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.policy.client; - -import java.io.Closeable; -import java.io.IOException; -import java.util.Collections; -import java.util.Map; -import javax.ws.rs.client.Entity; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; -import org.onap.policy.common.endpoints.http.client.HttpClient; -import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public abstract class AbstractHttpClient implements Closeable { - - private static final Logger LOGGER = LoggerFactory.getLogger(AbstractHttpClient.class); - private final HttpClient httpclient; - - /** - * Constructor. - * - * @param policyParticipantParameters the parameters for the policy participant - * @throws ControlLoopRuntimeException on client start errors - */ - protected AbstractHttpClient(BusTopicParams policyParticipantParameters) { - try { - httpclient = HttpClientFactoryInstance.getClientFactory().build(policyParticipantParameters); - } catch (final Exception e) { - throw new ControlLoopRuntimeException(Status.INTERNAL_SERVER_ERROR, " Client failed to start", e); - } - } - - protected Response executePost(String path, final Entity entity) { - var response = httpclient.post(path, entity, Map.of(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON, - HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)); - if (response.getStatus() / 100 != 2) { - LOGGER.error("Invocation of path {} failed for entity {}. Response status: {}, Response status info: {}", - path, entity, response.getStatus(), response.getStatusInfo()); - } - return response; - } - - protected Response executeDelete(String path) { - return httpclient.delete(path, Collections.emptyMap()); - } - - @Override - public void close() throws IOException { - httpclient.shutdown(); - } -} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/client/PolicyApiHttpClient.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/client/PolicyApiHttpClient.java deleted file mode 100644 index 38a79f7f6..000000000 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/client/PolicyApiHttpClient.java +++ /dev/null @@ -1,87 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.policy.client; - -import javax.ws.rs.client.Entity; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import org.onap.policy.clamp.controlloop.participant.policy.main.parameters.ParticipantPolicyParameters; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; -import org.springframework.stereotype.Component; - -@Component -public class PolicyApiHttpClient extends AbstractHttpClient { - - private static final String POLICY_URI = "/policy/api/v1/"; - - /** - * Constructor. - * - * @param parameters the policy participant parameters - */ - public PolicyApiHttpClient(ParticipantPolicyParameters parameters) { - super(parameters.getPolicyApiParameters()); - } - - /** - * Create Policy Types. - * - * @param toscaServiceTemplate the whole ToscaServiceTemplate - * @return Response - * @throws PfModelException on errors creating the policy type - */ - public Response createPolicyType(ToscaServiceTemplate toscaServiceTemplate) throws PfModelException { - return executePost(POLICY_URI + "policytypes", Entity.entity(toscaServiceTemplate, MediaType.APPLICATION_JSON)); - } - - /** - * Create Policies. - * - * @param toscaServiceTemplate the whole ToscaServiceTemplate - * @return Response - */ - public Response createPolicy(final ToscaServiceTemplate toscaServiceTemplate) { - return executePost(POLICY_URI + "policies", Entity.entity(toscaServiceTemplate, MediaType.APPLICATION_JSON)); - } - - /** - * Delete Policies. - * - * @param policyName the name of the policy to be deleted - * @param policyVersion the version of the policy to be deleted - * @return Response - */ - public Response deletePolicy(final String policyName, final String policyVersion) { - return executeDelete(POLICY_URI + "policies/" + policyName + "/versions/" + policyVersion); - } - - /** - * Delete Policy types. - * - * @param policyTypeName the name of the policy to be deleted - * @param policyTypeVersion the version of the policy to be deleted - * @return Response - */ - public Response deletePolicyType(final String policyTypeName, final String policyTypeVersion) { - return executeDelete(POLICY_URI + "policytypes/" + policyTypeName + "/versions/" + policyTypeVersion); - } -} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/client/PolicyPapHttpClient.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/client/PolicyPapHttpClient.java deleted file mode 100644 index f835c6e04..000000000 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/client/PolicyPapHttpClient.java +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.policy.client; - -import java.util.LinkedList; -import java.util.List; -import javax.ws.rs.client.Entity; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import org.onap.policy.clamp.controlloop.participant.policy.main.parameters.ParticipantPolicyParameters; -import org.onap.policy.models.pdp.concepts.DeploymentGroup; -import org.onap.policy.models.pdp.concepts.DeploymentGroups; -import org.onap.policy.models.pdp.concepts.DeploymentSubGroup; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.springframework.stereotype.Component; - -@Component -public class PolicyPapHttpClient extends AbstractHttpClient { - - private static final String PAP_URI = "/policy/pap/v1/"; - private final String pdpGroup; - private final String pdpType; - - /** - * Constructor. - * - * @param parameters the policy participant parameters - */ - public PolicyPapHttpClient(ParticipantPolicyParameters parameters) { - super(parameters.getPolicyPapParameters()); - this.pdpGroup = parameters.getPdpGroup(); - this.pdpType = parameters.getPdpType(); - } - - /** - * Deploy or undeploy Policies. - * - * @param policyName the name of the policy to be deployed/undeployed - * @param policyVersion the version of the policy to be deployed/undeployed - * @param action the action to deploy/undeploy policy - * @return Response - */ - public Response handlePolicyDeployOrUndeploy(final String policyName, final String policyVersion, - final DeploymentSubGroup.Action action) { - - List policies = new LinkedList(); - policies.add(new ToscaConceptIdentifier(policyName, policyVersion)); - - DeploymentSubGroup subGroup = new DeploymentSubGroup(); - subGroup.setPolicies(policies); - subGroup.setPdpType(pdpType); - subGroup.setAction(action); - - DeploymentGroup group = new DeploymentGroup(); - List subGroups = new LinkedList(); - subGroups.add(subGroup); - group.setDeploymentSubgroups(subGroups); - group.setName(pdpGroup); - - DeploymentGroups groups = new DeploymentGroups(); - List groupsArr = new LinkedList(); - groupsArr.add(group); - groups.setGroups(groupsArr); - - return executePost(PAP_URI + "pdps/deployments/batch", Entity.entity(groups, MediaType.APPLICATION_JSON)); - } -} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/ParticipantConfig.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/ParticipantConfig.java deleted file mode 100644 index 7b49a9a6b..000000000 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/ParticipantConfig.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.policy.config; - -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.clamp.controlloop.participant.policy.main.handler.ControlLoopElementHandler; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class ParticipantConfig { - - /** - * Register ControlLoopElementListener. - * - * @param intermediaryApi the ParticipantIntermediaryApi - * @param clElementHandler the ControlLoop Element Handler - */ - @Autowired - public void registerControlLoopElementListener(ParticipantIntermediaryApi intermediaryApi, - ControlLoopElementHandler clElementHandler) { - intermediaryApi.registerControlLoopElementListener(clElementHandler); - clElementHandler.setIntermediaryApi(intermediaryApi); - } -} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/SecurityConfig.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/SecurityConfig.java deleted file mode 100644 index 4ee8c41b0..000000000 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/SecurityConfig.java +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.policy.config; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@Configuration -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Value("${security.enable-csrf:true}") - private boolean csrfEnabled = true; - - @Override - protected void configure(HttpSecurity http) throws Exception { - // @formatter:off - http.authorizeRequests() - .antMatchers().authenticated() - .anyRequest().authenticated() - .and().httpBasic(); - // @formatter:on - - if (!csrfEnabled) { - http.csrf().disable(); - } - } -} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/ControlLoopElementHandler.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/ControlLoopElementHandler.java deleted file mode 100644 index 663d6d5e9..000000000 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/ControlLoopElementHandler.java +++ /dev/null @@ -1,220 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation. - * ================================================================================ - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.policy.main.handler; - -import java.time.Instant; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.UUID; -import lombok.Setter; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.clamp.controlloop.participant.policy.client.PolicyApiHttpClient; -import org.onap.policy.clamp.controlloop.participant.policy.client.PolicyPapHttpClient; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.base.PfModelRuntimeException; -import org.onap.policy.models.pdp.concepts.DeploymentSubGroup; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; -import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType; -import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -/** - * This class handles implementation of controlLoopElement updates. - */ -@Component -public class ControlLoopElementHandler implements ControlLoopElementListener { - - private static final Logger LOGGER = LoggerFactory.getLogger(ControlLoopElementHandler.class); - private final Map policyTypeMap = new LinkedHashMap<>(); - private final Map policyMap = new LinkedHashMap<>(); - - private final PolicyApiHttpClient apiHttpClient; - private final PolicyPapHttpClient papHttpClient; - - @Setter - private ParticipantIntermediaryApi intermediaryApi; - - /** - * constructor. - * - * @param apiHttpClient the Policy Api Http Client - * @param papHttpClient the Policy Pap Http Client - */ - public ControlLoopElementHandler(PolicyApiHttpClient apiHttpClient, PolicyPapHttpClient papHttpClient) { - this.papHttpClient = papHttpClient; - this.apiHttpClient = apiHttpClient; - } - - /** - * Callback method to handle a control loop element state change. - * - * @param controlLoopId the ID of the control loop - * @param controlLoopElementId the ID of the control loop element - * @param currentState the current state of the control loop element - * @param orderedState the state to which the control loop element is changing to - */ - @Override - public void controlLoopElementStateChange(ToscaConceptIdentifier controlLoopId, - UUID controlLoopElementId, ControlLoopState currentState, - ControlLoopOrderedState orderedState) { - switch (orderedState) { - case UNINITIALISED: - try { - undeployPolicies(controlLoopElementId); - deletePolicyData(controlLoopId, controlLoopElementId, orderedState); - intermediaryApi.updateControlLoopElementState(controlLoopId, - controlLoopElementId, orderedState, ControlLoopState.UNINITIALISED, - ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); - } catch (PfModelRuntimeException e) { - LOGGER.debug("Undeploying/Deleting policy failed {}", controlLoopElementId, e); - } - break; - case PASSIVE: - try { - undeployPolicies(controlLoopElementId); - } catch (PfModelRuntimeException e) { - LOGGER.debug("Undeploying policies failed - no policies to undeploy {}", controlLoopElementId); - } - intermediaryApi.updateControlLoopElementState(controlLoopId, - controlLoopElementId, orderedState, ControlLoopState.PASSIVE, - ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); - break; - case RUNNING: - LOGGER.info("Running state is not supported"); - break; - default: - LOGGER.debug("Unknown orderedstate {}", orderedState); - break; - } - } - - private void deletePolicyData(ToscaConceptIdentifier controlLoopId, - UUID controlLoopElementId, ControlLoopOrderedState newState) { - // Delete all policies of this controlLoop from policy framework - for (Entry policy : policyMap.entrySet()) { - apiHttpClient.deletePolicy(policy.getKey(), policy.getValue()); - } - policyMap.clear(); - // Delete all policy types of this control loop from policy framework - for (Entry policyType : policyTypeMap.entrySet()) { - apiHttpClient.deletePolicyType(policyType.getKey(), policyType.getValue()); - } - policyTypeMap.clear(); - intermediaryApi.updateControlLoopElementState(controlLoopId, - controlLoopElementId, newState, ControlLoopState.UNINITIALISED, - ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); - } - - private void deployPolicies(ToscaConceptIdentifier controlLoopId, UUID controlLoopElementId, - ControlLoopOrderedState newState) { - // Deploy all policies of this controlLoop from Policy Framework - if (policyMap.entrySet() != null) { - for (Entry policy : policyMap.entrySet()) { - papHttpClient.handlePolicyDeployOrUndeploy(policy.getKey(), policy.getValue(), - DeploymentSubGroup.Action.POST); - } - LOGGER.debug("Policies deployed to {} successfully", controlLoopElementId); - } else { - LOGGER.debug("No policies to deploy to {}", controlLoopElementId); - } - intermediaryApi.updateControlLoopElementState(controlLoopId, - controlLoopElementId, newState, ControlLoopState.PASSIVE, - ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); - } - - private void undeployPolicies(UUID controlLoopElementId) { - // Undeploy all policies of this controlloop from Policy Framework - if (policyMap.entrySet() != null) { - for (Entry policy : policyMap.entrySet()) { - papHttpClient.handlePolicyDeployOrUndeploy(policy.getKey(), policy.getValue(), - DeploymentSubGroup.Action.DELETE); - } - LOGGER.debug("Undeployed policies from {} successfully", controlLoopElementId); - } else { - LOGGER.debug("No policies are deployed to {}", controlLoopElementId); - } - } - - /** - * Callback method to handle an update on a control loop element. - * - * @param element the information on the control loop element - * @param clElementDefinition toscaNodeTemplate - * @throws PfModelException in case of an exception - */ - @Override - public void controlLoopElementUpdate(ToscaConceptIdentifier controlLoopId, ControlLoopElement element, - ToscaNodeTemplate clElementDefinition) - throws PfModelException { - ToscaServiceTemplate controlLoopDefinition = element.getToscaServiceTemplateFragment(); - if (controlLoopDefinition.getToscaTopologyTemplate() != null) { - if (controlLoopDefinition.getPolicyTypes() != null) { - for (ToscaPolicyType policyType : controlLoopDefinition.getPolicyTypes().values()) { - policyTypeMap.put(policyType.getName(), policyType.getVersion()); - } - LOGGER.debug("Found Policy Types in control loop definition: {} , Creating Policy Types", - controlLoopDefinition.getName()); - apiHttpClient.createPolicyType(controlLoopDefinition); - } - if (controlLoopDefinition.getToscaTopologyTemplate().getPolicies() != null) { - for (Map foundPolicyMap : controlLoopDefinition.getToscaTopologyTemplate() - .getPolicies()) { - for (ToscaPolicy policy : foundPolicyMap.values()) { - policyMap.put(policy.getName(), policy.getVersion()); - } - } - LOGGER.debug("Found Policies in control loop definition: {} , Creating Policies", - controlLoopDefinition.getName()); - apiHttpClient.createPolicy(controlLoopDefinition); - } - } - deployPolicies(controlLoopId, element.getId(), element.getOrderedState()); - } - - /** - * Handle controlLoopElement statistics. - * - * @param controlLoopElementId controlloop element id - */ - @Override - public void handleStatistics(UUID controlLoopElementId) throws PfModelException { - var clElement = intermediaryApi.getControlLoopElement(controlLoopElementId); - if (clElement != null) { - var clElementStatistics = new ClElementStatistics(); - clElementStatistics.setControlLoopState(clElement.getState()); - clElementStatistics.setTimeStamp(Instant.now()); - intermediaryApi.updateControlLoopElementStatistics(controlLoopElementId, clElementStatistics); - } - } -} \ No newline at end of file diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/ParticipantPolicyParameters.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/ParticipantPolicyParameters.java deleted file mode 100644 index 8e1de36b9..000000000 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/ParticipantPolicyParameters.java +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.policy.main.parameters; - -import javax.validation.Valid; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import lombok.Getter; -import lombok.Setter; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; -import org.onap.policy.common.endpoints.parameters.RestClientParameters; -import org.onap.policy.common.parameters.validation.ParameterGroupConstraint; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.validation.annotation.Validated; - -/** - * Class to hold all parameters needed for the policy participant. - * - */ -@Validated -@Getter -@Setter -@ConfigurationProperties(prefix = "participant") -public class ParticipantPolicyParameters implements ParticipantParameters { - - @NotNull - @Valid - private ParticipantIntermediaryParameters intermediaryParameters; - - @NotNull - @ParameterGroupConstraint - private RestClientParameters policyApiParameters; - - @NotNull - @ParameterGroupConstraint - private RestClientParameters policyPapParameters; - - @NotBlank - private String pdpGroup; - - @NotBlank - private String pdpType; -} diff --git a/participant/participant-impl/participant-impl-policy/src/main/resources/META-INF/persistence.xml b/participant/participant-impl/participant-impl-policy/src/main/resources/META-INF/persistence.xml index 46db712b6..383bc7418 100644 --- a/participant/participant-impl/participant-impl-policy/src/main/resources/META-INF/persistence.xml +++ b/participant/participant-impl/participant-impl-policy/src/main/resources/META-INF/persistence.xml @@ -52,11 +52,11 @@ org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate org.onap.policy.models.tosca.simple.concepts.JpaToscaTopologyTemplate org.onap.policy.models.tosca.simple.concepts.JpaToscaTrigger - org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaControlLoop - org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaControlLoopElement - org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaParticipant - org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaParticipantStatistics - org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaClElementStatistics + org.onap.policy.clamp.acm.models.acm.persistence.concepts.JpaAutomationComposition + org.onap.policy.clamp.acm.models.acm.persistence.concepts.JpaAutomationCompositionElement + org.onap.policy.clamp.acm.models.acm.persistence.concepts.JpaParticipant + org.onap.policy.clamp.acm.models.acm.persistence.concepts.JpaParticipantStatistics + org.onap.policy.clamp.acm.models.acm.persistence.concepts.JpaAcElementStatistics diff --git a/participant/participant-impl/participant-impl-policy/src/main/resources/config/application.yaml b/participant/participant-impl/participant-impl-policy/src/main/resources/config/application.yaml index 2aa33c1c4..c3338a993 100644 --- a/participant/participant-impl/participant-impl-policy/src/main/resources/config/application.yaml +++ b/participant/participant-impl/participant-impl-policy/src/main/resources/config/application.yaml @@ -30,19 +30,19 @@ participant: name: org.onap.PM_Policy version: 1.0.0 participantType: - name: org.onap.policy.controlloop.PolicyControlLoopParticipant + name: org.onap.policy.clamp.acm.PolicyParticipant version: 2.3.1 - clampControlLoopTopics: + clampAutomationCompositionTopics: topicSources: - - topic: POLICY-CLRUNTIME-PARTICIPANT + topic: POLICY-ACRUNTIME-PARTICIPANT servers: - ${topicServer:localhost} topicCommInfrastructure: dmaap fetchTimeout: 15000 topicSinks: - - topic: POLICY-CLRUNTIME-PARTICIPANT + topic: POLICY-ACRUNTIME-PARTICIPANT servers: - ${topicServer:localhost} topicCommInfrastructure: dmaap @@ -54,4 +54,4 @@ management: server: port: 8085 servlet: - context-path: /onap/policyparticipant + context-path: /onap/policy/clamp/acm/policyparticipant diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/endtoend/ParticipantMessagesTest.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/endtoend/ParticipantMessagesTest.java new file mode 100644 index 000000000..c17d2c53d --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/endtoend/ParticipantMessagesTest.java @@ -0,0 +1,174 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.policy.endtoend; + +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.junit.Assert.assertEquals; + +import java.time.Instant; +import java.util.Collections; +import java.util.UUID; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantDeregisterAckListener; +import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher; +import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantRegisterAckListener; +import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantUpdateListener; +import org.onap.policy.clamp.acm.participant.intermediary.handler.ParticipantHandler; +import org.onap.policy.clamp.acm.participant.policy.main.utils.TestListenerUtils; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantDeregister; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantDeregisterAck; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegister; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegisterAck; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantUpdate; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantUpdateAck; +import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +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.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@TestPropertySource(locations = {"classpath:application_test.properties"}) +class ParticipantMessagesTest { + + private static final Object lockit = new Object(); + private static final CommInfrastructure INFRA = CommInfrastructure.NOOP; + private static final String TOPIC = "my-topic"; + + @Autowired + private ParticipantHandler participantHandler; + + @Test + void testSendParticipantRegisterMessage() throws Exception { + final ParticipantRegister participantRegisterMsg = new ParticipantRegister(); + participantRegisterMsg.setParticipantId(getParticipantId()); + participantRegisterMsg.setTimestamp(Instant.now()); + participantRegisterMsg.setParticipantType(getParticipantType()); + + synchronized (lockit) { + ParticipantMessagePublisher participantMessagePublisher = + new ParticipantMessagePublisher(); + participantMessagePublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class))); + assertThatCode(() -> participantMessagePublisher.sendParticipantRegister(participantRegisterMsg)) + .doesNotThrowAnyException(); + } + } + + @Test + void testReceiveParticipantRegisterAckMessage() throws Exception { + final ParticipantRegisterAck participantRegisterAckMsg = new ParticipantRegisterAck(); + participantRegisterAckMsg.setMessage("ParticipantRegisterAck message"); + participantRegisterAckMsg.setResponseTo(UUID.randomUUID()); + participantRegisterAckMsg.setResult(true); + + synchronized (lockit) { + ParticipantRegisterAckListener participantRegisterAckListener = + new ParticipantRegisterAckListener(participantHandler); + assertThatCode(() -> participantRegisterAckListener.onTopicEvent(INFRA, TOPIC, null, + participantRegisterAckMsg)).doesNotThrowAnyException(); + } + } + + @Test + void testSendParticipantDeregisterMessage() throws Exception { + final ParticipantDeregister participantDeregisterMsg = new ParticipantDeregister(); + participantDeregisterMsg.setParticipantId(getParticipantId()); + participantDeregisterMsg.setTimestamp(Instant.now()); + participantDeregisterMsg.setParticipantType(getParticipantType()); + + synchronized (lockit) { + ParticipantMessagePublisher participantMessagePublisher = + new ParticipantMessagePublisher(); + participantMessagePublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class))); + assertThatCode(() -> participantMessagePublisher.sendParticipantDeregister(participantDeregisterMsg)) + .doesNotThrowAnyException(); + } + } + + @Test + void testReceiveParticipantDeregisterAckMessage() throws Exception { + final ParticipantDeregisterAck participantDeregisterAckMsg = new ParticipantDeregisterAck(); + participantDeregisterAckMsg.setMessage("ParticipantDeregisterAck message"); + participantDeregisterAckMsg.setResponseTo(UUID.randomUUID()); + participantDeregisterAckMsg.setResult(true); + + synchronized (lockit) { + ParticipantDeregisterAckListener participantDeregisterAckListener = + new ParticipantDeregisterAckListener(participantHandler); + assertThatCode(() -> participantDeregisterAckListener.onTopicEvent(INFRA, TOPIC, null, + participantDeregisterAckMsg)).doesNotThrowAnyException(); + } + } + + @Test + void testReceiveParticipantUpdateMessage() throws Exception { + ParticipantUpdate participantUpdateMsg = TestListenerUtils.createParticipantUpdateMsg(); + + synchronized (lockit) { + ParticipantUpdateListener participantUpdateListener = new ParticipantUpdateListener(participantHandler); + participantUpdateListener.onTopicEvent(INFRA, TOPIC, null, participantUpdateMsg); + } + + // Verify the result of GET participants with what is stored + assertEquals("org.onap.PM_Policy", participantHandler.getParticipantId().getName()); + } + + @Test + void testSendParticipantUpdateAckMessage() throws Exception { + final ParticipantUpdateAck participantUpdateAckMsg = new ParticipantUpdateAck(); + participantUpdateAckMsg.setMessage("ParticipantUpdateAck message"); + participantUpdateAckMsg.setResponseTo(UUID.randomUUID()); + participantUpdateAckMsg.setResult(true); + + synchronized (lockit) { + ParticipantMessagePublisher participantMessagePublisher = new ParticipantMessagePublisher(); + participantMessagePublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class))); + assertThatCode(() -> participantMessagePublisher.sendParticipantUpdateAck(participantUpdateAckMsg)) + .doesNotThrowAnyException(); + } + } + + @Test + void testParticipantStatusHeartbeat() throws Exception { + final ParticipantStatus heartbeat = participantHandler.makeHeartbeat(true); + synchronized (lockit) { + ParticipantMessagePublisher publisher = new ParticipantMessagePublisher(); + publisher.active(Collections.singletonList(Mockito.mock(TopicSink.class))); + assertThatCode(() -> publisher.sendHeartbeat(heartbeat)).doesNotThrowAnyException(); + } + } + + private ToscaConceptIdentifier getParticipantId() { + return new ToscaConceptIdentifier("org.onap.PM_Policy", "1.0.0"); + } + + private ToscaConceptIdentifier getParticipantType() { + return new ToscaConceptIdentifier("org.onap.policy.acm.PolicyAutomationCompositionParticipant", "2.3.1"); + } +} diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandlerTest.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandlerTest.java new file mode 100644 index 000000000..0d114db8d --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandlerTest.java @@ -0,0 +1,102 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.policy.main.handler; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.Mockito.when; + +import java.util.UUID; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.acm.participant.policy.client.PolicyApiHttpClient; +import org.onap.policy.clamp.acm.participant.policy.client.PolicyPapHttpClient; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; + +class AutomationCompositionElementHandlerTest { + + private static final String ID_NAME = "org.onap.PM_CDS_Blueprint"; + private static final String ID_VERSION = "1.0.1"; + private static final UUID automationCompositionElementId = UUID.randomUUID(); + private static final ToscaConceptIdentifier automationCompositionId = + new ToscaConceptIdentifier(ID_NAME, ID_VERSION); + + @Test + void testHandlerExceptions() { + AutomationCompositionElementHandler handler = getTestingHandler(); + + assertDoesNotThrow(() -> handler + .automationCompositionElementStateChange(automationCompositionId, + automationCompositionElementId, + AutomationCompositionState.UNINITIALISED, + AutomationCompositionOrderedState.PASSIVE)); + + assertDoesNotThrow(() -> handler + .automationCompositionElementStateChange(automationCompositionId, + automationCompositionElementId, + AutomationCompositionState.RUNNING, + AutomationCompositionOrderedState.UNINITIALISED)); + + assertDoesNotThrow(() -> handler + .automationCompositionElementStateChange(automationCompositionId, + automationCompositionElementId, + AutomationCompositionState.PASSIVE, + AutomationCompositionOrderedState.RUNNING)); + var element = getTestingAcElement(); + var acElementDefinition = Mockito.mock(ToscaNodeTemplate.class); + + assertDoesNotThrow(() -> handler + .automationCompositionElementUpdate(automationCompositionId, element, acElementDefinition)); + + assertDoesNotThrow(() -> handler + .handleStatistics(automationCompositionElementId)); + } + + AutomationCompositionElementHandler getTestingHandler() { + var api = Mockito.mock(PolicyApiHttpClient.class); + var pap = Mockito.mock(PolicyPapHttpClient.class); + var handler = new AutomationCompositionElementHandler(api, pap); + var intermediaryApi = Mockito.mock(ParticipantIntermediaryApi.class); + var element = getTestingAcElement(); + when(intermediaryApi.getAutomationCompositionElement(automationCompositionElementId)).thenReturn(element); + handler.setIntermediaryApi(intermediaryApi); + return handler; + } + + AutomationCompositionElement getTestingAcElement() { + var element = new AutomationCompositionElement(); + element.setDefinition(automationCompositionId); + element.setDescription("Description"); + element.setId(automationCompositionElementId); + element.setOrderedState(AutomationCompositionOrderedState.UNINITIALISED); + element.setParticipantId(automationCompositionId); + element.setState(AutomationCompositionState.UNINITIALISED); + var template = Mockito.mock(ToscaServiceTemplate.class); + element.setToscaServiceTemplateFragment(template); + return element; + } +} diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/parameters/CommonTestData.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/parameters/CommonTestData.java new file mode 100644 index 000000000..b5cd9d442 --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/parameters/CommonTestData.java @@ -0,0 +1,181 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.policy.main.parameters; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import org.onap.policy.clamp.acm.participant.policy.main.parameters.ParticipantPolicyParameters; +import org.onap.policy.common.endpoints.parameters.TopicParameters; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +/** + * Class to hold/create all parameters for test cases. + */ +public class CommonTestData { + public static final String PARTICIPANT_GROUP_NAME = "AutomationCompositionParticipantGroup"; + public static final String DESCRIPTION = "Participant description"; + public static final long TIME_INTERVAL = 2000; + public static final List TOPIC_PARAMS = Arrays.asList(getTopicParams()); + + public static final Coder CODER = new StandardCoder(); + + /** + * Get ParticipantPolicyParameters. + * + * @return ParticipantPolicyParameters + */ + public ParticipantPolicyParameters getParticipantPolicyParameters() { + try { + return CODER.convert(getParticipantPolicyParametersMap(PARTICIPANT_GROUP_NAME), + ParticipantPolicyParameters.class); + } catch (final CoderException e) { + throw new RuntimeException("cannot create ParticipantPolicyParameters from map", e); + } + } + + /** + * Returns a property map for a ParticipantPolicyParameters map for test cases. + * + * @param name name of the parameters + * + * @return a property map suitable for constructing an object + */ + public Map getParticipantPolicyParametersMap(final String name) { + final Map map = new TreeMap<>(); + + map.put("name", name); + map.put("intermediaryParameters", getIntermediaryParametersMap(false)); + map.put("policyApiParameters", getPolicyApiParametersMap()); + map.put("policyPapParameters", getPolicyPapParametersMap()); + map.put("pdpGroup", "defaultGroup"); + map.put("pdpType", "apex"); + return map; + } + + /** + * Returns a property map for a policyPapParameters map for test cases. + * + * @return a property map suitable for constructing an object + */ + public Map getPolicyPapParametersMap() { + final Map map = new TreeMap<>(); + map.put("clientName", "pap"); + map.put("hostname", "localhost"); + map.put("port", 6968); + map.put("userName", "policyadmin"); + map.put("password", "zb!XztG34"); + map.put("https", false); + map.put("allowSelfSignedCerts", true); + return map; + } + + /** + * Returns a property map for a policyApiParameters map for test cases. + * + * @return a property map suitable for constructing an object + */ + public Map getPolicyApiParametersMap() { + final Map map = new TreeMap<>(); + map.put("clientName", "api"); + map.put("hostname", "localhost"); + map.put("port", 6969); + map.put("userName", "policyadmin"); + map.put("password", "zb!XztG34"); + map.put("https", false); + map.put("allowSelfSignedCerts", true); + + return map; + } + + /** + * Returns a property map for a intermediaryParameters map for test cases. + * + * @param isEmpty boolean value to represent that object created should be empty or not + * @return a property map suitable for constructing an object + */ + public Map getIntermediaryParametersMap(final boolean isEmpty) { + final Map map = new TreeMap<>(); + if (!isEmpty) { + map.put("name", "Participant parameters"); + map.put("reportingTimeIntervalMs", TIME_INTERVAL); + map.put("description", DESCRIPTION); + map.put("participantId", getParticipantId()); + map.put("participantType", getParticipantId()); + map.put("clampAutomationCompositionTopics", getTopicParametersMap(false)); + } + + return map; + } + + /** + * Returns a property map for a TopicParameters map for test cases. + * + * @param isEmpty boolean value to represent that object created should be empty or not + * @return a property map suitable for constructing an object + */ + public Map getTopicParametersMap(final boolean isEmpty) { + final Map map = new TreeMap<>(); + if (!isEmpty) { + map.put("topicSources", TOPIC_PARAMS); + map.put("topicSinks", TOPIC_PARAMS); + } + return map; + } + + /** + * Returns topic parameters for test cases. + * + * @return topic parameters + */ + public static TopicParameters getTopicParams() { + final TopicParameters topicParams = new TopicParameters(); + topicParams.setTopic("POLICY-ACRUNTIME-PARTICIPANT"); + topicParams.setTopicCommInfrastructure("dmaap"); + topicParams.setServers(Arrays.asList("localhost")); + return topicParams; + } + + /** + * Returns participantId for test cases. + * + * @return participant Id + */ + public static ToscaConceptIdentifier getParticipantId() { + final ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_Policy", "0.0.0"); + return participantId; + } + + /** + * Nulls out a field within a JSON string. + * + * @param json JSON string + * @param field field to be nulled out + * @return a new JSON string with the field nulled out + */ + public String nullifyField(String json, String field) { + return json.replace(field + "\"", field + "\":null, \"" + field + "Xxx\""); + } +} diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/parameters/ParticipantPolicyParametersTest.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/parameters/ParticipantPolicyParametersTest.java new file mode 100644 index 000000000..89b2bce58 --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/parameters/ParticipantPolicyParametersTest.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.policy.main.parameters; + +import static org.assertj.core.api.Assertions.assertThat; + +import javax.validation.Validation; +import javax.validation.ValidatorFactory; +import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.acm.participant.policy.main.parameters.ParticipantPolicyParameters; + +class ParticipantPolicyParametersTest { + private final CommonTestData commonTestData = new CommonTestData(); + private final ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); + + @Test + void testParticipantPolicyParameters() { + final ParticipantPolicyParameters participantParameters = commonTestData.getParticipantPolicyParameters(); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isEmpty(); + } + + @Test + void testParticipantPolicyParameters_NullTopicSinks() { + final ParticipantPolicyParameters participantParameters = commonTestData.getParticipantPolicyParameters(); + participantParameters.getIntermediaryParameters().getClampAutomationCompositionTopics().setTopicSinks(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } + + @Test + void testParticipantPolicyParameters_NullTopicSources() { + final ParticipantPolicyParameters participantParameters = commonTestData.getParticipantPolicyParameters(); + participantParameters.getIntermediaryParameters().getClampAutomationCompositionTopics().setTopicSources(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } + + @Test + void testParticipantPolicyParameters_NullPolicyApiParameters() { + final ParticipantPolicyParameters participantParameters = commonTestData.getParticipantPolicyParameters(); + participantParameters.setPolicyApiParameters(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } + + @Test + void testParticipantPolicyParameters_NullHostname() { + final ParticipantPolicyParameters participantParameters = commonTestData.getParticipantPolicyParameters(); + participantParameters.getPolicyApiParameters().setHostname(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } +} diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/rest/ActuatorControllerTest.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/rest/ActuatorControllerTest.java new file mode 100644 index 000000000..8543bf98a --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/rest/ActuatorControllerTest.java @@ -0,0 +1,92 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.policy.main.rest; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import javax.ws.rs.client.Invocation; +import javax.ws.rs.core.Response; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.onap.policy.clamp.acm.participant.policy.main.utils.CommonActuatorController; +import org.springframework.boot.test.autoconfigure.actuate.metrics.AutoConfigureMetrics; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@AutoConfigureMetrics +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@TestPropertySource(locations = {"classpath:application_test.properties"}) +class ActuatorControllerTest extends CommonActuatorController { + + private static final String HEALTH_ENDPOINT = "health"; + private static final String METRICS_ENDPOINT = "metrics"; + private static final String PROMETHEUS_ENDPOINT = "prometheus"; + + @LocalServerPort + private int randomServerPort; + + @BeforeEach + public void setUpPort() { + super.setHttpPrefix(randomServerPort); + } + + @Test + void testGetHealth_Unauthorized() throws Exception { + assertUnauthorizedActGet(HEALTH_ENDPOINT); + } + + @Test + void testGetMetrics_Unauthorized() throws Exception { + assertUnauthorizedActGet(METRICS_ENDPOINT); + } + + @Test + void testGetPrometheus_Unauthorized() throws Exception { + assertUnauthorizedActGet(PROMETHEUS_ENDPOINT); + } + + @Test + void testGetHealth() throws Exception { + Invocation.Builder invocationBuilder = super.sendActRequest(HEALTH_ENDPOINT); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + } + + @Test + void testGetMetrics() throws Exception { + Invocation.Builder invocationBuilder = super.sendActRequest(METRICS_ENDPOINT); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + } + + @Test + void testGePrometheus() throws Exception { + Invocation.Builder invocationBuilder = super.sendActRequest(PROMETHEUS_ENDPOINT); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + } + +} diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/utils/CommonActuatorController.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/utils/CommonActuatorController.java new file mode 100644 index 000000000..689977e3c --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/utils/CommonActuatorController.java @@ -0,0 +1,114 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.policy.main.utils; + +import static org.junit.Assert.assertEquals; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.glassfish.jersey.client.ClientProperties; +import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; +import org.onap.policy.common.gson.GsonMessageBodyHandler; +import org.onap.policy.common.utils.network.NetworkUtil; + +/** + * Class to perform Rest unit tests. + * + */ +public class CommonActuatorController { + + public static final String SELF = NetworkUtil.getHostname(); + public static final String CONTEXT_PATH = "onap/policy/clamp/acm/policyparticipant"; + public static final String ACTUATOR_ENDPOINT = CONTEXT_PATH + "/actuator/"; + + private static String httpPrefix; + + /** + * Sends a request to an actuator endpoint. + * + * @param endpoint the target endpoint + * @return a request builder + * @throws Exception if an error occurs + */ + protected Invocation.Builder sendActRequest(final String endpoint) throws Exception { + return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + endpoint, true); + } + + /** + * Sends a request to an actuator endpoint, without any authorization header. + * + * @param endpoint the target endpoint + * @return a request builder + * @throws Exception if an error occurs + */ + protected Invocation.Builder sendNoAuthActRequest(final String endpoint) throws Exception { + return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + endpoint, false); + } + + /** + * Sends a request to a fully qualified endpoint. + * + * @param fullyQualifiedEndpoint the fully qualified target endpoint + * @param includeAuth if authorization header should be included + * @return a request builder + * @throws Exception if an error occurs + */ + protected Invocation.Builder sendFqeRequest(final String fullyQualifiedEndpoint, boolean includeAuth) + throws Exception { + final Client client = ClientBuilder.newBuilder().build(); + + client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true"); + client.register(GsonMessageBodyHandler.class); + + if (includeAuth) { + client.register(HttpAuthenticationFeature.basic("participantUser", "zb!XztG34")); + } + + final WebTarget webTarget = client.target(fullyQualifiedEndpoint); + + return webTarget.request(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN); + } + + /** + * Assert that GET call to actuator endpoint is Unauthorized. + * + * @param endPoint the endpoint + * @throws Exception if an error occurs + */ + protected void assertUnauthorizedActGet(final String endPoint) throws Exception { + Response rawresp = sendNoAuthActRequest(endPoint).buildGet().invoke(); + assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus()); + } + + /** + * Set Up httpPrefix. + * + * @param port the port + */ + protected void setHttpPrefix(int port) { + httpPrefix = "http://" + SELF + ":" + port + "/"; + } + +} diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/utils/TestListenerUtils.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/utils/TestListenerUtils.java new file mode 100644 index 000000000..a29831d56 --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/utils/TestListenerUtils.java @@ -0,0 +1,321 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.policy.main.utils; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileNotFoundException; +import java.time.Instant; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition; +import org.onap.policy.clamp.models.acm.concepts.ParticipantUpdates; +import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionStateChange; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionUpdate; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantUpdate; +import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.coder.YamlJsonTranslator; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class TestListenerUtils { + + private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator(); + private static final Coder CODER = new StandardCoder(); + private static final Logger LOGGER = LoggerFactory.getLogger(TestListenerUtils.class); + + /** + * Method to create a automationComposition from a yaml file. + * + * @return AutomationComposition automation composition + */ + public static AutomationComposition createAutomationComposition() { + AutomationComposition automationComposition = new AutomationComposition(); + Map elements = new LinkedHashMap<>(); + ToscaServiceTemplate toscaServiceTemplate = testAutomationCompositionRead(); + Map nodeTemplatesMap = + toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates(); + for (Map.Entry toscaInputEntry : nodeTemplatesMap.entrySet()) { + AutomationCompositionElement acElement = new AutomationCompositionElement(); + acElement.setId(UUID.randomUUID()); + + ToscaConceptIdentifier acElementParticipantId = new ToscaConceptIdentifier(); + acElementParticipantId.setName(toscaInputEntry.getKey()); + acElementParticipantId.setVersion(toscaInputEntry.getValue().getVersion()); + acElement.setParticipantId(acElementParticipantId); + + acElement.setDefinition(acElementParticipantId); + acElement.setState(AutomationCompositionState.UNINITIALISED); + acElement.setDescription(toscaInputEntry.getValue().getDescription()); + acElement.setOrderedState(AutomationCompositionOrderedState.UNINITIALISED); + elements.put(acElement.getId(), acElement); + } + automationComposition.setElements(elements); + automationComposition.setName("PMSHInstance0"); + automationComposition.setVersion("1.0.0"); + + ToscaConceptIdentifier definition = new ToscaConceptIdentifier(); + definition.setName("PMSHInstance0"); + definition.setVersion("1.0.0"); + automationComposition.setDefinition(definition); + + return automationComposition; + } + + /** + * Method to create AutomationCompositionStateChange message from the arguments passed. + * + * @param automationCompositionOrderedState automationCompositionOrderedState + * @return AutomationCompositionStateChange message + */ + public static AutomationCompositionStateChange createAutomationCompositionStateChangeMsg( + final AutomationCompositionOrderedState automationCompositionOrderedState) { + final AutomationCompositionStateChange acStateChangeMsg = new AutomationCompositionStateChange(); + + ToscaConceptIdentifier automationCompositionId = new ToscaConceptIdentifier(); + automationCompositionId.setName("PMSHInstance0"); + automationCompositionId.setVersion("1.0.0"); + + ToscaConceptIdentifier participantId = new ToscaConceptIdentifier(); + participantId.setName("org.onap.PM_Policy"); + participantId.setVersion("0.0.0"); + + acStateChangeMsg.setAutomationCompositionId(automationCompositionId); + acStateChangeMsg.setParticipantId(participantId); + acStateChangeMsg.setTimestamp(Instant.now()); + acStateChangeMsg.setOrderedState(automationCompositionOrderedState); + + return acStateChangeMsg; + } + + /** + * Method to create AutomationCompositionUpdateMsg. + * + * @return AutomationCompositionUpdate message + */ + public static AutomationCompositionUpdate createAutomationCompositionUpdateMsg() { + final AutomationCompositionUpdate acUpdateMsg = new AutomationCompositionUpdate(); + ToscaConceptIdentifier automationCompositionId = new ToscaConceptIdentifier("PMSHInstance0", "1.0.0"); + ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_Policy", "0.0.0"); + + acUpdateMsg.setAutomationCompositionId(automationCompositionId); + acUpdateMsg.setParticipantId(participantId); + acUpdateMsg.setMessageId(UUID.randomUUID()); + acUpdateMsg.setTimestamp(Instant.now()); + + Map elements = new LinkedHashMap<>(); + ToscaServiceTemplate toscaServiceTemplate = testAutomationCompositionRead(); + TestListenerUtils.addPoliciesToToscaServiceTemplate(toscaServiceTemplate); + Map nodeTemplatesMap = + toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates(); + for (Map.Entry toscaInputEntry : nodeTemplatesMap.entrySet()) { + if (ParticipantUtils.checkIfNodeTemplateIsAutomationCompositionElement(toscaInputEntry.getValue(), + toscaServiceTemplate)) { + AutomationCompositionElement acElement = new AutomationCompositionElement(); + acElement.setId(UUID.randomUUID()); + var acParticipantType = + ParticipantUtils.findParticipantType(toscaInputEntry.getValue().getProperties()); + + acElement.setParticipantId(acParticipantType); + acElement.setParticipantType(acParticipantType); + + acElement.setDefinition( + new ToscaConceptIdentifier(toscaInputEntry.getKey(), toscaInputEntry.getValue().getVersion())); + acElement.setState(AutomationCompositionState.UNINITIALISED); + acElement.setDescription(toscaInputEntry.getValue().getDescription()); + acElement.setOrderedState(AutomationCompositionOrderedState.PASSIVE); + elements.put(acElement.getId(), acElement); + } + } + + List participantUpdates = new ArrayList<>(); + for (AutomationCompositionElement element : elements.values()) { + AcmUtils.setServiceTemplatePolicyInfo(element, toscaServiceTemplate); + AcmUtils.prepareParticipantUpdate(element, participantUpdates); + } + acUpdateMsg.setParticipantUpdatesList(participantUpdates); + return acUpdateMsg; + } + + /** + * Method to create participantUpdateMsg. + * + * @return ParticipantUpdate message + */ + public static ParticipantUpdate createParticipantUpdateMsg() { + final ParticipantUpdate participantUpdateMsg = new ParticipantUpdate(); + ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_Policy", "1.0.0"); + ToscaConceptIdentifier participantType = + new ToscaConceptIdentifier("org.onap.policy.acm.PolicyAutomationCompositionParticipant", "2.3.1"); + + participantUpdateMsg.setParticipantId(participantId); + participantUpdateMsg.setTimestamp(Instant.now()); + participantUpdateMsg.setParticipantType(participantType); + participantUpdateMsg.setTimestamp(Instant.ofEpochMilli(3000)); + participantUpdateMsg.setMessageId(UUID.randomUUID()); + + ToscaServiceTemplate toscaServiceTemplate = testAutomationCompositionRead(); + // Add policies to the toscaServiceTemplate + TestListenerUtils.addPoliciesToToscaServiceTemplate(toscaServiceTemplate); + + List participantDefinitionUpdates = new ArrayList<>(); + for (Map.Entry toscaInputEntry : toscaServiceTemplate.getToscaTopologyTemplate() + .getNodeTemplates().entrySet()) { + if (ParticipantUtils.checkIfNodeTemplateIsAutomationCompositionElement(toscaInputEntry.getValue(), + toscaServiceTemplate)) { + AcmUtils.prepareParticipantDefinitionUpdate( + ParticipantUtils.findParticipantType(toscaInputEntry.getValue().getProperties()), + toscaInputEntry.getKey(), toscaInputEntry.getValue(), + participantDefinitionUpdates, null); + } + } + + participantUpdateMsg.setParticipantDefinitionUpdates(participantDefinitionUpdates); + return participantUpdateMsg; + } + + /** + * Method to create AutomationCompositionUpdate using the arguments passed. + * + * @param jsonFilePath the path of the automation composition content + * @return AutomationCompositionUpdate message + * @throws CoderException exception while reading the file to object + */ + public static AutomationCompositionUpdate createParticipantAcUpdateMsgFromJson(String jsonFilePath) + throws CoderException { + AutomationCompositionUpdate automationCompositionUpdateMsg = + CODER.decode(new File(jsonFilePath), AutomationCompositionUpdate.class); + return automationCompositionUpdateMsg; + } + + private static ToscaServiceTemplate testAutomationCompositionRead() { + Set automationCompositionDirectoryContents = + ResourceUtils.getDirectoryContents("src/test/resources/utils/servicetemplates"); + + boolean atLeastOneAutomationCompositionTested = false; + ToscaServiceTemplate toscaServiceTemplate = null; + + for (String automationCompositionFilePath : automationCompositionDirectoryContents) { + if (!automationCompositionFilePath.endsWith(".yaml")) { + continue; + } + atLeastOneAutomationCompositionTested = true; + toscaServiceTemplate = testAutomationCompositionYamlSerialization(automationCompositionFilePath); + } + + // Add policy_types to the toscaServiceTemplate + addPolicyTypesToToscaServiceTemplate(toscaServiceTemplate); + + assertTrue(atLeastOneAutomationCompositionTested); + return toscaServiceTemplate; + } + + private static void addPolicyTypesToToscaServiceTemplate(ToscaServiceTemplate toscaServiceTemplate) { + Set policyTypeDirectoryContents = ResourceUtils.getDirectoryContents("policytypes"); + + for (String policyTypeFilePath : policyTypeDirectoryContents) { + String policyTypeString = ResourceUtils.getResourceAsString(policyTypeFilePath); + + ToscaServiceTemplate foundPolicyTypeSt = + yamlTranslator.fromYaml(policyTypeString, ToscaServiceTemplate.class); + + toscaServiceTemplate.setDerivedFrom(foundPolicyTypeSt.getDerivedFrom()); + toscaServiceTemplate.setDescription(foundPolicyTypeSt.getDescription()); + toscaServiceTemplate.setMetadata(foundPolicyTypeSt.getMetadata()); + toscaServiceTemplate.setName(foundPolicyTypeSt.getName()); + toscaServiceTemplate.setToscaDefinitionsVersion(foundPolicyTypeSt.getToscaDefinitionsVersion()); + toscaServiceTemplate.setVersion(foundPolicyTypeSt.getVersion()); + + if (foundPolicyTypeSt.getDataTypes() != null) { + if (toscaServiceTemplate.getDataTypes() == null) { + toscaServiceTemplate.setDataTypes(foundPolicyTypeSt.getDataTypes()); + } else { + toscaServiceTemplate.getDataTypes().putAll(foundPolicyTypeSt.getDataTypes()); + } + } + + if (toscaServiceTemplate.getPolicyTypes() == null) { + toscaServiceTemplate.setPolicyTypes(foundPolicyTypeSt.getPolicyTypes()); + } else { + toscaServiceTemplate.getPolicyTypes().putAll(foundPolicyTypeSt.getPolicyTypes()); + } + } + } + + /** + * Method to add polcies to the toscaServiceTemplate. + * + * @param toscaServiceTemplate to add policies + */ + public static void addPoliciesToToscaServiceTemplate(ToscaServiceTemplate toscaServiceTemplate) { + Set policiesDirectoryContents = ResourceUtils.getDirectoryContents("policies"); + + for (String policiesFilePath : policiesDirectoryContents) { + if (!policiesFilePath.endsWith("yaml")) { + continue; + } + + String policiesString = ResourceUtils.getResourceAsString(policiesFilePath); + + ToscaServiceTemplate foundPoliciesSt = + yamlTranslator.fromYaml(policiesString, ToscaServiceTemplate.class); + toscaServiceTemplate.getToscaTopologyTemplate() + .setPolicies(foundPoliciesSt.getToscaTopologyTemplate().getPolicies()); + } + } + + private static ToscaServiceTemplate testAutomationCompositionYamlSerialization( + String automationCompositionFilePath) { + try { + String automationCompositionString = ResourceUtils.getResourceAsString(automationCompositionFilePath); + if (automationCompositionString == null) { + throw new FileNotFoundException(automationCompositionFilePath); + } + + ToscaServiceTemplate serviceTemplate = + yamlTranslator.fromYaml(automationCompositionString, ToscaServiceTemplate.class); + return serviceTemplate; + } catch (FileNotFoundException e) { + LOGGER.error("cannot find YAML file", automationCompositionFilePath); + throw new IllegalArgumentException(e); + } + } +} diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/endtoend/ParticipantMessagesTest.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/endtoend/ParticipantMessagesTest.java deleted file mode 100644 index ce368eba1..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/endtoend/ParticipantMessagesTest.java +++ /dev/null @@ -1,174 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.policy.endtoend; - -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.junit.Assert.assertEquals; - -import java.time.Instant; -import java.util.Collections; -import java.util.UUID; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mockito; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregister; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregisterAck; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegister; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegisterAck; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatus; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdateAck; -import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantDeregisterAckListener; -import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantMessagePublisher; -import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantRegisterAckListener; -import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantUpdateListener; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler; -import org.onap.policy.clamp.controlloop.participant.policy.main.utils.TestListenerUtils; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.event.comm.TopicSink; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -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.test.context.TestPropertySource; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@ExtendWith(SpringExtension.class) -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -@TestPropertySource(locations = {"classpath:application_test.properties"}) -class ParticipantMessagesTest { - - private static final Object lockit = new Object(); - private static final CommInfrastructure INFRA = CommInfrastructure.NOOP; - private static final String TOPIC = "my-topic"; - - @Autowired - private ParticipantHandler participantHandler; - - @Test - void testSendParticipantRegisterMessage() throws Exception { - final ParticipantRegister participantRegisterMsg = new ParticipantRegister(); - participantRegisterMsg.setParticipantId(getParticipantId()); - participantRegisterMsg.setTimestamp(Instant.now()); - participantRegisterMsg.setParticipantType(getParticipantType()); - - synchronized (lockit) { - ParticipantMessagePublisher participantMessagePublisher = - new ParticipantMessagePublisher(); - participantMessagePublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class))); - assertThatCode(() -> participantMessagePublisher.sendParticipantRegister(participantRegisterMsg)) - .doesNotThrowAnyException(); - } - } - - @Test - void testReceiveParticipantRegisterAckMessage() throws Exception { - final ParticipantRegisterAck participantRegisterAckMsg = new ParticipantRegisterAck(); - participantRegisterAckMsg.setMessage("ParticipantRegisterAck message"); - participantRegisterAckMsg.setResponseTo(UUID.randomUUID()); - participantRegisterAckMsg.setResult(true); - - synchronized (lockit) { - ParticipantRegisterAckListener participantRegisterAckListener = - new ParticipantRegisterAckListener(participantHandler); - assertThatCode(() -> participantRegisterAckListener.onTopicEvent(INFRA, TOPIC, null, - participantRegisterAckMsg)).doesNotThrowAnyException(); - } - } - - @Test - void testSendParticipantDeregisterMessage() throws Exception { - final ParticipantDeregister participantDeregisterMsg = new ParticipantDeregister(); - participantDeregisterMsg.setParticipantId(getParticipantId()); - participantDeregisterMsg.setTimestamp(Instant.now()); - participantDeregisterMsg.setParticipantType(getParticipantType()); - - synchronized (lockit) { - ParticipantMessagePublisher participantMessagePublisher = - new ParticipantMessagePublisher(); - participantMessagePublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class))); - assertThatCode(() -> participantMessagePublisher.sendParticipantDeregister(participantDeregisterMsg)) - .doesNotThrowAnyException(); - } - } - - @Test - void testReceiveParticipantDeregisterAckMessage() throws Exception { - final ParticipantDeregisterAck participantDeregisterAckMsg = new ParticipantDeregisterAck(); - participantDeregisterAckMsg.setMessage("ParticipantDeregisterAck message"); - participantDeregisterAckMsg.setResponseTo(UUID.randomUUID()); - participantDeregisterAckMsg.setResult(true); - - synchronized (lockit) { - ParticipantDeregisterAckListener participantDeregisterAckListener = - new ParticipantDeregisterAckListener(participantHandler); - assertThatCode(() -> participantDeregisterAckListener.onTopicEvent(INFRA, TOPIC, null, - participantDeregisterAckMsg)).doesNotThrowAnyException(); - } - } - - @Test - void testReceiveParticipantUpdateMessage() throws Exception { - ParticipantUpdate participantUpdateMsg = TestListenerUtils.createParticipantUpdateMsg(); - - synchronized (lockit) { - ParticipantUpdateListener participantUpdateListener = new ParticipantUpdateListener(participantHandler); - participantUpdateListener.onTopicEvent(INFRA, TOPIC, null, participantUpdateMsg); - } - - // Verify the result of GET participants with what is stored - assertEquals("org.onap.PM_Policy", participantHandler.getParticipantId().getName()); - } - - @Test - void testSendParticipantUpdateAckMessage() throws Exception { - final ParticipantUpdateAck participantUpdateAckMsg = new ParticipantUpdateAck(); - participantUpdateAckMsg.setMessage("ParticipantUpdateAck message"); - participantUpdateAckMsg.setResponseTo(UUID.randomUUID()); - participantUpdateAckMsg.setResult(true); - - synchronized (lockit) { - ParticipantMessagePublisher participantMessagePublisher = new ParticipantMessagePublisher(); - participantMessagePublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class))); - assertThatCode(() -> participantMessagePublisher.sendParticipantUpdateAck(participantUpdateAckMsg)) - .doesNotThrowAnyException(); - } - } - - @Test - void testParticipantStatusHeartbeat() throws Exception { - final ParticipantStatus heartbeat = participantHandler.makeHeartbeat(true); - synchronized (lockit) { - ParticipantMessagePublisher publisher = new ParticipantMessagePublisher(); - publisher.active(Collections.singletonList(Mockito.mock(TopicSink.class))); - assertThatCode(() -> publisher.sendHeartbeat(heartbeat)).doesNotThrowAnyException(); - } - } - - private ToscaConceptIdentifier getParticipantId() { - return new ToscaConceptIdentifier("org.onap.PM_Policy", "1.0.0"); - } - - private ToscaConceptIdentifier getParticipantType() { - return new ToscaConceptIdentifier("org.onap.policy.controlloop.PolicyControlLoopParticipant", "2.3.1"); - } -} diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/ControlLoopElementHandlerTest.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/ControlLoopElementHandlerTest.java deleted file mode 100644 index b5c5e19cb..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/ControlLoopElementHandlerTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.policy.main.handler; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.mockito.Mockito.when; - -import java.util.UUID; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.clamp.controlloop.participant.policy.client.PolicyApiHttpClient; -import org.onap.policy.clamp.controlloop.participant.policy.client.PolicyPapHttpClient; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; - -class ControlLoopElementHandlerTest { - - private static final String ID_NAME = "org.onap.PM_CDS_Blueprint"; - private static final String ID_VERSION = "1.0.1"; - private static final UUID controlLoopElementId = UUID.randomUUID(); - private static final ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); - - @Test - void testHandlerExceptions() throws PfModelException { - ControlLoopElementHandler handler = getTestingHandler(); - - assertDoesNotThrow(() -> handler - .controlLoopElementStateChange(controlLoopId, - controlLoopElementId, - ControlLoopState.UNINITIALISED, - ControlLoopOrderedState.PASSIVE)); - - assertDoesNotThrow(() -> handler - .controlLoopElementStateChange(controlLoopId, - controlLoopElementId, - ControlLoopState.RUNNING, - ControlLoopOrderedState.UNINITIALISED)); - - assertDoesNotThrow(() -> handler - .controlLoopElementStateChange(controlLoopId, - controlLoopElementId, - ControlLoopState.PASSIVE, - ControlLoopOrderedState.RUNNING)); - var element = getTestingClElement(); - var clElementDefinition = Mockito.mock(ToscaNodeTemplate.class); - - assertDoesNotThrow(() -> handler - .controlLoopElementUpdate(controlLoopId, element, clElementDefinition)); - - assertDoesNotThrow(() -> handler - .handleStatistics(controlLoopElementId)); - } - - ControlLoopElementHandler getTestingHandler() { - var api = Mockito.mock(PolicyApiHttpClient.class); - var pap = Mockito.mock(PolicyPapHttpClient.class); - var handler = new ControlLoopElementHandler(api, pap); - var intermediaryApi = Mockito.mock(ParticipantIntermediaryApi.class); - var element = getTestingClElement(); - when(intermediaryApi.getControlLoopElement(controlLoopElementId)).thenReturn(element); - handler.setIntermediaryApi(intermediaryApi); - return handler; - } - - ControlLoopElement getTestingClElement() { - var element = new ControlLoopElement(); - element.setDefinition(controlLoopId); - element.setDescription("Description"); - element.setId(controlLoopElementId); - element.setOrderedState(ControlLoopOrderedState.UNINITIALISED); - element.setParticipantId(controlLoopId); - element.setState(ControlLoopState.UNINITIALISED); - var template = Mockito.mock(ToscaServiceTemplate.class); - element.setToscaServiceTemplateFragment(template); - return element; - } - -} diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/CommonTestData.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/CommonTestData.java deleted file mode 100644 index e965370cc..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/CommonTestData.java +++ /dev/null @@ -1,180 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.policy.main.parameters; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import org.onap.policy.common.endpoints.parameters.TopicParameters; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; - -/** - * Class to hold/create all parameters for test cases. - */ -public class CommonTestData { - public static final String PARTICIPANT_GROUP_NAME = "ControlLoopParticipantGroup"; - public static final String DESCRIPTION = "Participant description"; - public static final long TIME_INTERVAL = 2000; - public static final List TOPIC_PARAMS = Arrays.asList(getTopicParams()); - - public static final Coder CODER = new StandardCoder(); - - /** - * Get ParticipantPolicyParameters. - * - * @return ParticipantPolicyParameters - */ - public ParticipantPolicyParameters getParticipantPolicyParameters() { - try { - return CODER.convert(getParticipantPolicyParametersMap(PARTICIPANT_GROUP_NAME), - ParticipantPolicyParameters.class); - } catch (final CoderException e) { - throw new RuntimeException("cannot create ParticipantPolicyParameters from map", e); - } - } - - /** - * Returns a property map for a ParticipantPolicyParameters map for test cases. - * - * @param name name of the parameters - * - * @return a property map suitable for constructing an object - */ - public Map getParticipantPolicyParametersMap(final String name) { - final Map map = new TreeMap<>(); - - map.put("name", name); - map.put("intermediaryParameters", getIntermediaryParametersMap(false)); - map.put("policyApiParameters", getPolicyApiParametersMap()); - map.put("policyPapParameters", getPolicyPapParametersMap()); - map.put("pdpGroup", "defaultGroup"); - map.put("pdpType", "apex"); - return map; - } - - /** - * Returns a property map for a policyPapParameters map for test cases. - * - * @return a property map suitable for constructing an object - */ - public Map getPolicyPapParametersMap() { - final Map map = new TreeMap<>(); - map.put("clientName", "pap"); - map.put("hostname", "localhost"); - map.put("port", 6968); - map.put("userName", "policyadmin"); - map.put("password", "zb!XztG34"); - map.put("https", false); - map.put("allowSelfSignedCerts", true); - return map; - } - - /** - * Returns a property map for a policyApiParameters map for test cases. - * - * @return a property map suitable for constructing an object - */ - public Map getPolicyApiParametersMap() { - final Map map = new TreeMap<>(); - map.put("clientName", "api"); - map.put("hostname", "localhost"); - map.put("port", 6969); - map.put("userName", "policyadmin"); - map.put("password", "zb!XztG34"); - map.put("https", false); - map.put("allowSelfSignedCerts", true); - - return map; - } - - /** - * Returns a property map for a intermediaryParameters map for test cases. - * - * @param isEmpty boolean value to represent that object created should be empty or not - * @return a property map suitable for constructing an object - */ - public Map getIntermediaryParametersMap(final boolean isEmpty) { - final Map map = new TreeMap<>(); - if (!isEmpty) { - map.put("name", "Participant parameters"); - map.put("reportingTimeIntervalMs", TIME_INTERVAL); - map.put("description", DESCRIPTION); - map.put("participantId", getParticipantId()); - map.put("participantType", getParticipantId()); - map.put("clampControlLoopTopics", getTopicParametersMap(false)); - } - - return map; - } - - /** - * Returns a property map for a TopicParameters map for test cases. - * - * @param isEmpty boolean value to represent that object created should be empty or not - * @return a property map suitable for constructing an object - */ - public Map getTopicParametersMap(final boolean isEmpty) { - final Map map = new TreeMap<>(); - if (!isEmpty) { - map.put("topicSources", TOPIC_PARAMS); - map.put("topicSinks", TOPIC_PARAMS); - } - return map; - } - - /** - * Returns topic parameters for test cases. - * - * @return topic parameters - */ - public static TopicParameters getTopicParams() { - final TopicParameters topicParams = new TopicParameters(); - topicParams.setTopic("POLICY-CLRUNTIME-PARTICIPANT"); - topicParams.setTopicCommInfrastructure("dmaap"); - topicParams.setServers(Arrays.asList("localhost")); - return topicParams; - } - - /** - * Returns participantId for test cases. - * - * @return participant Id - */ - public static ToscaConceptIdentifier getParticipantId() { - final ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_Policy", "0.0.0"); - return participantId; - } - - /** - * Nulls out a field within a JSON string. - * - * @param json JSON string - * @param field field to be nulled out - * @return a new JSON string with the field nulled out - */ - public String nullifyField(String json, String field) { - return json.replace(field + "\"", field + "\":null, \"" + field + "Xxx\""); - } -} diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/ParticipantPolicyParametersTest.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/ParticipantPolicyParametersTest.java deleted file mode 100644 index 74e7cb1bc..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/ParticipantPolicyParametersTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.policy.main.parameters; - -import static org.assertj.core.api.Assertions.assertThat; - -import javax.validation.Validation; -import javax.validation.ValidatorFactory; -import org.junit.jupiter.api.Test; - -class ParticipantPolicyParametersTest { - private CommonTestData commonTestData = new CommonTestData(); - private ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); - - @Test - void testParticipantPolicyParameters() { - final ParticipantPolicyParameters participantParameters = commonTestData.getParticipantPolicyParameters(); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isEmpty(); - } - - @Test - void testParticipantPolicyParameters_NullTopicSinks() { - final ParticipantPolicyParameters participantParameters = commonTestData.getParticipantPolicyParameters(); - participantParameters.getIntermediaryParameters().getClampControlLoopTopics().setTopicSinks(null); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); - } - - @Test - void testParticipantPolicyParameters_NullTopicSources() { - final ParticipantPolicyParameters participantParameters = commonTestData.getParticipantPolicyParameters(); - participantParameters.getIntermediaryParameters().getClampControlLoopTopics().setTopicSources(null); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); - } - - @Test - void testParticipantPolicyParameters_NullPolicyApiParameters() { - final ParticipantPolicyParameters participantParameters = commonTestData.getParticipantPolicyParameters(); - participantParameters.setPolicyApiParameters(null); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); - } - - @Test - void testParticipantPolicyParameters_NullHostname() { - final ParticipantPolicyParameters participantParameters = commonTestData.getParticipantPolicyParameters(); - participantParameters.getPolicyApiParameters().setHostname(null); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); - } -} diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/rest/ActuatorControllerTest.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/rest/ActuatorControllerTest.java deleted file mode 100644 index 9cc16e287..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/rest/ActuatorControllerTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.policy.main.rest; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import javax.ws.rs.client.Invocation; -import javax.ws.rs.core.Response; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.onap.policy.clamp.controlloop.participant.policy.main.utils.CommonActuatorController; -import org.springframework.boot.test.autoconfigure.actuate.metrics.AutoConfigureMetrics; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@AutoConfigureMetrics -@ExtendWith(SpringExtension.class) -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -@TestPropertySource(locations = {"classpath:application_test.properties"}) -class ActuatorControllerTest extends CommonActuatorController { - - private static final String HEALTH_ENDPOINT = "health"; - private static final String METRICS_ENDPOINT = "metrics"; - private static final String PROMETHEUS_ENDPOINT = "prometheus"; - - @LocalServerPort - private int randomServerPort; - - @BeforeEach - public void setUpPort() { - super.setHttpPrefix(randomServerPort); - } - - @Test - void testGetHealth_Unauthorized() throws Exception { - assertUnauthorizedActGet(HEALTH_ENDPOINT); - } - - @Test - void testGetMetrics_Unauthorized() throws Exception { - assertUnauthorizedActGet(METRICS_ENDPOINT); - } - - @Test - void testGetPrometheus_Unauthorized() throws Exception { - assertUnauthorizedActGet(PROMETHEUS_ENDPOINT); - } - - @Test - void testGetHealth() throws Exception { - Invocation.Builder invocationBuilder = super.sendActRequest(HEALTH_ENDPOINT); - Response rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); - } - - @Test - void testGetMetrics() throws Exception { - Invocation.Builder invocationBuilder = super.sendActRequest(METRICS_ENDPOINT); - Response rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); - } - - @Test - void testGePrometheus() throws Exception { - Invocation.Builder invocationBuilder = super.sendActRequest(PROMETHEUS_ENDPOINT); - Response rawresp = invocationBuilder.buildGet().invoke(); - assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); - } - -} diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/utils/CommonActuatorController.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/utils/CommonActuatorController.java deleted file mode 100644 index ec6e30918..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/utils/CommonActuatorController.java +++ /dev/null @@ -1,114 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.policy.main.utils; - -import static org.junit.Assert.assertEquals; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Invocation; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import org.glassfish.jersey.client.ClientProperties; -import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; -import org.onap.policy.common.gson.GsonMessageBodyHandler; -import org.onap.policy.common.utils.network.NetworkUtil; - -/** - * Class to perform Rest unit tests. - * - */ -public class CommonActuatorController { - - public static final String SELF = NetworkUtil.getHostname(); - public static final String CONTEXT_PATH = "onap/policyparticipant"; - public static final String ACTUATOR_ENDPOINT = CONTEXT_PATH + "/actuator/"; - - private static String httpPrefix; - - /** - * Sends a request to an actuator endpoint. - * - * @param endpoint the target endpoint - * @return a request builder - * @throws Exception if an error occurs - */ - protected Invocation.Builder sendActRequest(final String endpoint) throws Exception { - return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + endpoint, true); - } - - /** - * Sends a request to an actuator endpoint, without any authorization header. - * - * @param endpoint the target endpoint - * @return a request builder - * @throws Exception if an error occurs - */ - protected Invocation.Builder sendNoAuthActRequest(final String endpoint) throws Exception { - return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + endpoint, false); - } - - /** - * Sends a request to a fully qualified endpoint. - * - * @param fullyQualifiedEndpoint the fully qualified target endpoint - * @param includeAuth if authorization header should be included - * @return a request builder - * @throws Exception if an error occurs - */ - protected Invocation.Builder sendFqeRequest(final String fullyQualifiedEndpoint, boolean includeAuth) - throws Exception { - final Client client = ClientBuilder.newBuilder().build(); - - client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true"); - client.register(GsonMessageBodyHandler.class); - - if (includeAuth) { - client.register(HttpAuthenticationFeature.basic("participantUser", "zb!XztG34")); - } - - final WebTarget webTarget = client.target(fullyQualifiedEndpoint); - - return webTarget.request(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN); - } - - /** - * Assert that GET call to actuator endpoint is Unauthorized. - * - * @param endPoint the endpoint - * @throws Exception if an error occurs - */ - protected void assertUnauthorizedActGet(final String endPoint) throws Exception { - Response rawresp = sendNoAuthActRequest(endPoint).buildGet().invoke(); - assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus()); - } - - /** - * Set Up httpPrefix. - * - * @param port the port - */ - protected void setHttpPrefix(int port) { - httpPrefix = "http://" + SELF + ":" + port + "/"; - } - -} diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/utils/TestListenerUtils.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/utils/TestListenerUtils.java deleted file mode 100644 index d517ef61e..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/utils/TestListenerUtils.java +++ /dev/null @@ -1,317 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.policy.main.utils; - -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.FileNotFoundException; -import java.time.Instant; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.onap.policy.clamp.controlloop.common.utils.CommonUtils; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUpdates; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUtils; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopStateChange; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate; -import org.onap.policy.clamp.controlloop.participant.policy.main.parameters.CommonTestData; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.onap.policy.common.utils.coder.YamlJsonTranslator; -import org.onap.policy.common.utils.resources.ResourceUtils; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public final class TestListenerUtils { - - private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator(); - private static final Coder CODER = new StandardCoder(); - static CommonTestData commonTestData = new CommonTestData(); - private static final Logger LOGGER = LoggerFactory.getLogger(TestListenerUtils.class); - - /** - * Method to create a controlLoop from a yaml file. - * - * @return ControlLoop controlloop - */ - public static ControlLoop createControlLoop() { - ControlLoop controlLoop = new ControlLoop(); - Map elements = new LinkedHashMap<>(); - ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead(); - Map nodeTemplatesMap = - toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates(); - for (Map.Entry toscaInputEntry : nodeTemplatesMap.entrySet()) { - ControlLoopElement clElement = new ControlLoopElement(); - clElement.setId(UUID.randomUUID()); - - ToscaConceptIdentifier clElementParticipantId = new ToscaConceptIdentifier(); - clElementParticipantId.setName(toscaInputEntry.getKey()); - clElementParticipantId.setVersion(toscaInputEntry.getValue().getVersion()); - clElement.setParticipantId(clElementParticipantId); - - clElement.setDefinition(clElementParticipantId); - clElement.setState(ControlLoopState.UNINITIALISED); - clElement.setDescription(toscaInputEntry.getValue().getDescription()); - clElement.setOrderedState(ControlLoopOrderedState.UNINITIALISED); - elements.put(clElement.getId(), clElement); - } - controlLoop.setElements(elements); - controlLoop.setName("PMSHInstance0"); - controlLoop.setVersion("1.0.0"); - - ToscaConceptIdentifier definition = new ToscaConceptIdentifier(); - definition.setName("PMSHInstance0"); - definition.setVersion("1.0.0"); - controlLoop.setDefinition(definition); - - return controlLoop; - } - - /** - * Method to create ControlLoopStateChange message from the arguments passed. - * - * @param controlLoopOrderedState controlLoopOrderedState - * - * @return ControlLoopStateChange message - */ - public static ControlLoopStateChange createControlLoopStateChangeMsg( - final ControlLoopOrderedState controlLoopOrderedState) { - final ControlLoopStateChange clStateChangeMsg = new ControlLoopStateChange(); - - ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier(); - controlLoopId.setName("PMSHInstance0"); - controlLoopId.setVersion("1.0.0"); - - ToscaConceptIdentifier participantId = new ToscaConceptIdentifier(); - participantId.setName("org.onap.PM_Policy"); - participantId.setVersion("0.0.0"); - - clStateChangeMsg.setControlLoopId(controlLoopId); - clStateChangeMsg.setParticipantId(participantId); - clStateChangeMsg.setTimestamp(Instant.now()); - clStateChangeMsg.setOrderedState(controlLoopOrderedState); - - return clStateChangeMsg; - } - - /** - * Method to create ControlLoopUpdateMsg. - * - * @return ControlLoopUpdate message - */ - public static ControlLoopUpdate createControlLoopUpdateMsg() { - final ControlLoopUpdate clUpdateMsg = new ControlLoopUpdate(); - ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier("PMSHInstance0", "1.0.0"); - ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_Policy", "0.0.0"); - - clUpdateMsg.setControlLoopId(controlLoopId); - clUpdateMsg.setParticipantId(participantId); - clUpdateMsg.setMessageId(UUID.randomUUID()); - clUpdateMsg.setTimestamp(Instant.now()); - - Map elements = new LinkedHashMap<>(); - ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead(); - TestListenerUtils.addPoliciesToToscaServiceTemplate(toscaServiceTemplate); - Map nodeTemplatesMap = - toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates(); - for (Map.Entry toscaInputEntry : nodeTemplatesMap.entrySet()) { - if (ParticipantUtils.checkIfNodeTemplateIsControlLoopElement(toscaInputEntry.getValue(), - toscaServiceTemplate)) { - ControlLoopElement clElement = new ControlLoopElement(); - clElement.setId(UUID.randomUUID()); - var clParticipantType = - ParticipantUtils.findParticipantType(toscaInputEntry.getValue().getProperties()); - - clElement.setParticipantId(clParticipantType); - clElement.setParticipantType(clParticipantType); - - clElement.setDefinition( - new ToscaConceptIdentifier(toscaInputEntry.getKey(), toscaInputEntry.getValue().getVersion())); - clElement.setState(ControlLoopState.UNINITIALISED); - clElement.setDescription(toscaInputEntry.getValue().getDescription()); - clElement.setOrderedState(ControlLoopOrderedState.PASSIVE); - elements.put(clElement.getId(), clElement); - } - } - - List participantUpdates = new ArrayList<>(); - for (ControlLoopElement element : elements.values()) { - CommonUtils.setServiceTemplatePolicyInfo(element, toscaServiceTemplate); - CommonUtils.prepareParticipantUpdate(element, participantUpdates); - } - clUpdateMsg.setParticipantUpdatesList(participantUpdates); - return clUpdateMsg; - } - - /** - * Method to create participantUpdateMsg. - * - * @return ParticipantUpdate message - */ - public static ParticipantUpdate createParticipantUpdateMsg() { - final ParticipantUpdate participantUpdateMsg = new ParticipantUpdate(); - ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_Policy", "1.0.0"); - ToscaConceptIdentifier participantType = - new ToscaConceptIdentifier("org.onap.policy.controlloop.PolicyControlLoopParticipant", "2.3.1"); - - participantUpdateMsg.setParticipantId(participantId); - participantUpdateMsg.setTimestamp(Instant.now()); - participantUpdateMsg.setParticipantType(participantType); - participantUpdateMsg.setTimestamp(Instant.ofEpochMilli(3000)); - participantUpdateMsg.setMessageId(UUID.randomUUID()); - - ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead(); - // Add policies to the toscaServiceTemplate - TestListenerUtils.addPoliciesToToscaServiceTemplate(toscaServiceTemplate); - - List participantDefinitionUpdates = new ArrayList<>(); - for (Map.Entry toscaInputEntry : toscaServiceTemplate.getToscaTopologyTemplate() - .getNodeTemplates().entrySet()) { - if (ParticipantUtils.checkIfNodeTemplateIsControlLoopElement(toscaInputEntry.getValue(), - toscaServiceTemplate)) { - CommonUtils.prepareParticipantDefinitionUpdate( - ParticipantUtils.findParticipantType(toscaInputEntry.getValue().getProperties()), - toscaInputEntry.getKey(), toscaInputEntry.getValue(), - participantDefinitionUpdates, null); - } - } - - participantUpdateMsg.setParticipantDefinitionUpdates(participantDefinitionUpdates); - return participantUpdateMsg; - } - - /** - * Method to create ControlLoopUpdate using the arguments passed. - * - * @param jsonFilePath the path of the controlloop content - * - * @return ControlLoopUpdate message - * @throws CoderException exception while reading the file to object - */ - public static ControlLoopUpdate createParticipantClUpdateMsgFromJson(String jsonFilePath) throws CoderException { - ControlLoopUpdate controlLoopUpdateMsg = CODER.decode(new File(jsonFilePath), ControlLoopUpdate.class); - return controlLoopUpdateMsg; - } - - private static ToscaServiceTemplate testControlLoopRead() { - Set controlLoopDirectoryContents = - ResourceUtils.getDirectoryContents("src/test/resources/utils/servicetemplates"); - - boolean atLeastOneControlLoopTested = false; - ToscaServiceTemplate toscaServiceTemplate = null; - - for (String controlLoopFilePath : controlLoopDirectoryContents) { - if (!controlLoopFilePath.endsWith(".yaml")) { - continue; - } - atLeastOneControlLoopTested = true; - toscaServiceTemplate = testControlLoopYamlSerialization(controlLoopFilePath); - } - - // Add policy_types to the toscaServiceTemplate - addPolicyTypesToToscaServiceTemplate(toscaServiceTemplate); - - assertTrue(atLeastOneControlLoopTested); - return toscaServiceTemplate; - } - - private static void addPolicyTypesToToscaServiceTemplate(ToscaServiceTemplate toscaServiceTemplate) { - Set policyTypeDirectoryContents = ResourceUtils.getDirectoryContents("policytypes"); - - for (String policyTypeFilePath : policyTypeDirectoryContents) { - String policyTypeString = ResourceUtils.getResourceAsString(policyTypeFilePath); - - ToscaServiceTemplate foundPolicyTypeSt = - yamlTranslator.fromYaml(policyTypeString, ToscaServiceTemplate.class); - - toscaServiceTemplate.setDerivedFrom(foundPolicyTypeSt.getDerivedFrom()); - toscaServiceTemplate.setDescription(foundPolicyTypeSt.getDescription()); - toscaServiceTemplate.setMetadata(foundPolicyTypeSt.getMetadata()); - toscaServiceTemplate.setName(foundPolicyTypeSt.getName()); - toscaServiceTemplate.setToscaDefinitionsVersion(foundPolicyTypeSt.getToscaDefinitionsVersion()); - toscaServiceTemplate.setVersion(foundPolicyTypeSt.getVersion()); - - if (foundPolicyTypeSt.getDataTypes() != null) { - if (toscaServiceTemplate.getDataTypes() == null) { - toscaServiceTemplate.setDataTypes(foundPolicyTypeSt.getDataTypes()); - } else { - toscaServiceTemplate.getDataTypes().putAll(foundPolicyTypeSt.getDataTypes()); - } - } - - if (toscaServiceTemplate.getPolicyTypes() == null) { - toscaServiceTemplate.setPolicyTypes(foundPolicyTypeSt.getPolicyTypes()); - } else { - toscaServiceTemplate.getPolicyTypes().putAll(foundPolicyTypeSt.getPolicyTypes()); - } - } - } - - /** - * Method to add polcies to the toscaServiceTemplate. - * - * @param toscaServiceTemplate to add policies - */ - public static void addPoliciesToToscaServiceTemplate(ToscaServiceTemplate toscaServiceTemplate) { - Set policiesDirectoryContents = ResourceUtils.getDirectoryContents("policies"); - - for (String policiesFilePath : policiesDirectoryContents) { - String policiesString = ResourceUtils.getResourceAsString(policiesFilePath); - - ToscaServiceTemplate foundPoliciesSt = yamlTranslator.fromYaml(policiesString, ToscaServiceTemplate.class); - toscaServiceTemplate.getToscaTopologyTemplate() - .setPolicies(foundPoliciesSt.getToscaTopologyTemplate().getPolicies()); - } - } - - private static ToscaServiceTemplate testControlLoopYamlSerialization(String controlLoopFilePath) { - try { - String controlLoopString = ResourceUtils.getResourceAsString(controlLoopFilePath); - if (controlLoopString == null) { - throw new FileNotFoundException(controlLoopFilePath); - } - - ToscaServiceTemplate serviceTemplate = - yamlTranslator.fromYaml(controlLoopString, ToscaServiceTemplate.class); - return serviceTemplate; - } catch (FileNotFoundException e) { - LOGGER.error("cannot find YAML file", controlLoopFilePath); - throw new IllegalArgumentException(e); - } - } -} diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/application_test.properties b/participant/participant-impl/participant-impl-policy/src/test/resources/application_test.properties index 49781407d..932d9f2c3 100644 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/application_test.properties +++ b/participant/participant-impl/participant-impl-policy/src/test/resources/application_test.properties @@ -1,6 +1,6 @@ spring.security.user.name=participantUser spring.security.user.password=zb!XztG34 -server.servlet.context-path=/onap/policyparticipant +server.servlet.context-path=/onap/policy/clamp/acm/policyparticipant server.error.path=/error server.http-port=8085 @@ -15,14 +15,14 @@ participant.intermediaryParameters.reportingTimeInterval: 120000 participant.intermediaryParameters.description: Participant Description participant.intermediaryParameters.participantId.name: org.onap.PM_Policy participant.intermediaryParameters.participantId.version: 1.0.0 -participant.intermediaryParameters.participantType.name: org.onap.policy.controlloop.PolicyControlLoopParticipant +participant.intermediaryParameters.participantType.name: org.onap.policy.acm.PolicyAutomationCompositionParticipant participant.intermediaryParameters.participantType.version: 2.3.1 -participant.intermediaryParameters.clampControlLoopTopics.name=ControlLoop Topics -participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].topic=POLICY-CLRUNTIME-PARTICIPANT -participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].servers[0]=localhost -participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].topicCommInfrastructure=dmaap -participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].fetchTimeout=15000 -participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].topic=POLICY-CLRUNTIME-PARTICIPANT -participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].servers[0]=localhost -participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].topicCommInfrastructure=dmaap +participant.intermediaryParameters.clampAutomationCompositionTopics.name=Automation Composition Topics +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSources[0].topic=POLICY-ACRUNTIME-PARTICIPANT +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSources[0].servers[0]=localhost +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSources[0].topicCommInfrastructure=dmaap +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSources[0].fetchTimeout=15000 +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSinks[0].topic=POLICY-ACRUNTIME-PARTICIPANT +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSinks[0].servers[0]=localhost +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSinks[0].topicCommInfrastructure=dmaap management.endpoints.web.exposure.include=health,metrics,prometheus diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/parameters/TestACParams.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/parameters/TestACParams.yaml new file mode 100644 index 000000000..3e5782cdc --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/test/resources/parameters/TestACParams.yaml @@ -0,0 +1,172 @@ +tosca_definitions_version: "tosca_simple_yaml_1_3" +data_types: + onap.datatypes.ToscaConceptIdentifier: + derived_from: tosca.datatypes.Root + properties: + name: + type: string + required: true + version: + type: string + required: true +node_types: + org.onap.policy.clamp.acm.Participant: + version: 1.0.1 + derived_from: tosca.nodetypes.Root + properties: + provider: + type: string + requred: false + org.onap.policy.clamp.acm.AutomationCompositionElement: + version: 1.0.1 + derived_from: tosca.nodetypes.Root + properties: + provider: + type: string + requred: false + participantType: + type: onap.datatypes.ToscaConceptIdentifier + requred: true + startPhase: + type: integer + required: false + constraints: + - greater-or-equal: 0 + metadata: + common: true + description: A value indicating the start phase in which this automation composition element will be started, + the first start phase is zero. Automation Composition Elements are started in their start_phase + order and stopped in reverse start phase order. Automation Composition Elements with the same start phase are + started and stopped simultaneously + org.onap.policy.clamp.acm.AutomationComposition: + version: 1.0.1 + derived_from: tosca.nodetypes.Root + properties: + provider: + type: string + requred: false + elements: + type: list + required: true + entry_schema: + type: onap.datatypes.ToscaConceptIdentifier + org.onap.policy.clamp.acm.DCAEMicroserviceAutomationCompositionElement: + version: 1.0.1 + derived_from: org.onap.policy.clamp.acm.AutomationCompositionElement + properties: + dcae_blueprint_id: + type: onap.datatypes.ToscaConceptIdentifier + requred: true + org.onap.policy.clamp.acm.PolicyTypeAutomationCompositionElement: + version: 1.0.1 + derived_from: org.onap.policy.clamp.acm.AutomationCompositionElement + properties: + policy_type_id: + type: onap.datatypes.ToscaConceptIdentifier + requred: true + org.onap.policy.clamp.acm.CDSAutomationCompositionElement: + version: 1.0.1 + derived_from: org.onap.policy.clamp.acm.AutomationCompositionElement + properties: + cds_blueprint_id: + type: onap.datatypes.ToscaConceptIdentifier + requred: true +topology_template: + node_templates: + org.onap.dcae.acm.DCAEMicroserviceAutomationCompositionParticipant: + version: 2.3.4 + type: org.onap.policy.clamp.acm.Participant + type_version: 1.0.1 + description: Participant for DCAE microservices + properties: + provider: ONAP + org.onap.policy.acm.MonitoringPolicyAutomationCompositionParticipant: + version: 2.3.1 + type: org.onap.policy.clamp.acm.Participant + type_version: 1.0.1 + description: Participant for DCAE microservices + properties: + provider: ONAP + org.onap.policy.acm.OperationalPolicyAutomationCompositionParticipant: + version: 3.2.1 + type: org.onap.policy.clamp.acm.Participant + type_version: 1.0.1 + description: Participant for DCAE microservices + properties: + provider: ONAP + org.onap.ccsdk.cds.acm.CdsAutomationCompositionParticipant: + version: 2.2.1 + type: org.onap.policy.clamp.acm.Participant + type_version: 1.0.1 + description: Participant for DCAE microservices + properties: + provider: ONAP + org.onap.domain.pmsh.PMSH_DCAEMicroservice: + version: 1.2.3 + type: org.onap.policy.clamp.acm.DCAEMicroserviceAutomationCompositionElement + type_version: 1.0.0 + description: Automation composition element, DCAE microservice for Performance Management Subscription Handling + properties: + provider: Ericsson + participantType: + name: org.onap.dcae.acm.DCAEMicroserviceAutomationCompositionParticipant + version: 2.3.4 + dcae_blueprint_id: + name: org.onap.dcae.blueprints.PMSHBlueprint + version: 1.0.0 + org.onap.domain.pmsh.PMSH_MonitoringPolicyAutomationCompositionElement: + version: 1.2.3 + type: org.onap.policy.clamp.acm.PolicyTypeAutomationCompositionElement + type_version: 1.0.0 + description: Automation composition element, monitoring policy for Performance Management Subscription Handling + properties: + provider: Ericsson + participantType: + name: org.onap.policy.acm.MonitoringPolicyAutomationCompositionParticipant + version: 2.3.1 + policy_type_id: + name: onap.policies.monitoring.pm-subscription-handler + version: 1.0.0 + org.onap.domain.pmsh.PMSH_OperationalPolicyAutomationCompositionElement: + version: 1.2.3 + type: org.onap.policy.clamp.acm.PolicyTypeAutomationCompositionElement + type_version: 1.0.0 + description: Automation composition element, operational policy for Performance Management Subscription Handling + properties: + provider: Ericsson + participantType: + name: org.onap.policy.acm.OperationalPolicyAutomationCompositionParticipant + version: 2.2.1 + policy_type_id: + name: onap.policies.operational.pm-subscription-handler + version: 1.0.0 + org.onap.domain.pmsh.PMSH_CDS_AutomationCompositionElement: + version: 1.2.3 + type: org.onap.policy.clamp.acm.AutomationCompositionElement + type_version: 1.0.0 + description: Automation composition element for CDS for Performance Management Subscription Handling + properties: + provider: Ericsson + participantType: + name: org.onap.ccsdk.cds.acm.CdsAutomationCompositionParticipant + version: 3.2.1 + cds_blueprint_id: + name: org.onap.ccsdk.cds.PMSHCdsBlueprint + version: 1.0.0 + org.onap.domain.pmsh.PMSHAutomationCompositionDefinition: + version: 1.2.3 + type: org.onap.policy.clamp.acm.AutomationComposition + type_version: 1.0.0 + description: Automation composition for Performance Management Subscription Handling + properties: + provider: Ericsson + elements: + - name: org.onap.domain.pmsh.PMSH_DCAEMicroservice + version: 1.2.3 + - name: org.onap.domain.pmsh.PMSH_MonitoringPolicyAutomationCompositionElement + version: 1.2.3 + - name: org.onap.domain.pmsh.PMSH_OperationalPolicyAutomationCompositionElement + version: 1.2.3 + - name: org.onap.domain.pmsh.PMSH_CDS_AutomationCompositionElement + version: 1.2.3 + diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/parameters/TestCLParams.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/parameters/TestCLParams.yaml deleted file mode 100644 index 2ef3c6da0..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/parameters/TestCLParams.yaml +++ /dev/null @@ -1,172 +0,0 @@ -tosca_definitions_version: "tosca_simple_yaml_1_3" -data_types: - onap.datatypes.ToscaConceptIdentifier: - derived_from: tosca.datatypes.Root - properties: - name: - type: string - required: true - version: - type: string - required: true -node_types: - org.onap.policy.clamp.controlloop.Participant: - version: 1.0.1 - derived_from: tosca.nodetypes.Root - properties: - provider: - type: string - requred: false - org.onap.policy.clamp.controlloop.ControlLoopElement: - version: 1.0.1 - derived_from: tosca.nodetypes.Root - properties: - provider: - type: string - requred: false - participantType: - type: onap.datatypes.ToscaConceptIdentifier - requred: true - startPhase: - type: integer - required: false - constraints: - - greater-or-equal: 0 - metadata: - common: true - description: A value indicating the start phase in which this control loop element will be started, the - first start phase is zero. Control Loop Elements are started in their start_phase order and stopped - in reverse start phase order. Control Loop Elements with the same start phase are started and - stopped simultaneously - org.onap.policy.clamp.controlloop.ControlLoop: - version: 1.0.1 - derived_from: tosca.nodetypes.Root - properties: - provider: - type: string - requred: false - elements: - type: list - required: true - entry_schema: - type: onap.datatypes.ToscaConceptIdentifier - org.onap.policy.clamp.controlloop.DCAEMicroserviceControlLoopElement: - version: 1.0.1 - derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement - properties: - dcae_blueprint_id: - type: onap.datatypes.ToscaConceptIdentifier - requred: true - org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement: - version: 1.0.1 - derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement - properties: - policy_type_id: - type: onap.datatypes.ToscaConceptIdentifier - requred: true - org.onap.policy.clamp.controlloop.CDSControlLoopElement: - version: 1.0.1 - derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement - properties: - cds_blueprint_id: - type: onap.datatypes.ToscaConceptIdentifier - requred: true -topology_template: - node_templates: - org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant: - version: 2.3.4 - type: org.onap.policy.clamp.controlloop.Participant - type_version: 1.0.1 - description: Participant for DCAE microservices - properties: - provider: ONAP - org.onap.policy.controlloop.MonitoringPolicyControlLoopParticipant: - version: 2.3.1 - type: org.onap.policy.clamp.controlloop.Participant - type_version: 1.0.1 - description: Participant for DCAE microservices - properties: - provider: ONAP - org.onap.policy.controlloop.OperationalPolicyControlLoopParticipant: - version: 3.2.1 - type: org.onap.policy.clamp.controlloop.Participant - type_version: 1.0.1 - description: Participant for DCAE microservices - properties: - provider: ONAP - org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant: - version: 2.2.1 - type: org.onap.policy.clamp.controlloop.Participant - type_version: 1.0.1 - description: Participant for DCAE microservices - properties: - provider: ONAP - org.onap.domain.pmsh.PMSH_DCAEMicroservice: - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.DCAEMicroserviceControlLoopElement - type_version: 1.0.0 - description: Control loop element for the DCAE microservice for Performance Management Subscription Handling - properties: - provider: Ericsson - participantType: - name: org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant - version: 2.3.4 - dcae_blueprint_id: - name: org.onap.dcae.blueprints.PMSHBlueprint - version: 1.0.0 - org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement: - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement - type_version: 1.0.0 - description: Control loop element for the monitoring policy for Performance Management Subscription Handling - properties: - provider: Ericsson - participantType: - name: org.onap.policy.controlloop.MonitoringPolicyControlLoopParticipant - version: 2.3.1 - policy_type_id: - name: onap.policies.monitoring.pm-subscription-handler - version: 1.0.0 - org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement: - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement - type_version: 1.0.0 - description: Control loop element for the operational policy for Performance Management Subscription Handling - properties: - provider: Ericsson - participantType: - name: org.onap.policy.controlloop.OperationalPolicyControlLoopParticipant - version: 2.2.1 - policy_type_id: - name: onap.policies.operational.pm-subscription-handler - version: 1.0.0 - org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement: - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.ControlLoopElement - type_version: 1.0.0 - description: Control loop element for CDS for Performance Management Subscription Handling - properties: - provider: Ericsson - participantType: - name: org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant - version: 3.2.1 - cds_blueprint_id: - name: org.onap.ccsdk.cds.PMSHCdsBlueprint - version: 1.0.0 - org.onap.domain.pmsh.PMSHControlLoopDefinition: - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.ControlLoop - type_version: 1.0.0 - description: Control loop for Performance Management Subscription Handling - properties: - provider: Ericsson - elements: - - name: org.onap.domain.pmsh.PMSH_DCAEMicroservice - version: 1.2.3 - - name: org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement - version: 1.2.3 - - name: org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement - version: 1.2.3 - - name: org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement - version: 1.2.3 - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/parameters/logback-test.xml b/participant/participant-impl/participant-impl-policy/src/test/resources/parameters/logback-test.xml index cf6b89eb9..0f1d28be7 100644 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/parameters/logback-test.xml +++ b/participant/participant-impl/participant-impl-policy/src/test/resources/parameters/logback-test.xml @@ -36,7 +36,7 @@ - + diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policies/vCPE.policies.optimization.input.tosca.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policies/vCPE.policies.optimization.input.tosca.yaml deleted file mode 100644 index 126e8e6e2..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policies/vCPE.policies.optimization.input.tosca.yaml +++ /dev/null @@ -1,348 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -topology_template: - policies: - - - OSDF_CASABLANCA.Affinity_Default: - type: onap.policies.optimization.resource.AffinityPolicy - version: 1.0.0 - type_version: 1.0.0 - name: OSDF_CASABLANCA.Affinity_Default - metadata: - policy-id: OSDF_CASABLANCA.Affinity_Default - policy-version: 1 - properties: - scope: [] - services: [] - resources: [] - geography: [] - identity: affinity_vCPE - applicableResources: any - affinityProperties: - qualifier: same - category: complex - - - OSDF_CASABLANCA.Affinity_Default_US: - type: onap.policies.optimization.resource.AffinityPolicy - version: 1.0.0 - type_version: 1.0.0 - name: OSDF_CASABLANCA.Affinity_Default_US - metadata: - policy-id: OSDF_CASABLANCA.Affinity_Default_US - policy-version: 1 - properties: - scope: [] - services: [] - resources: [] - geography: [US] - identity: affinity_vCPE - applicableResources: any - affinityProperties: - qualifier: same - category: complex - - - OSDF_CASABLANCA.Affinity_Default_vCPE_US_0: - type: onap.policies.optimization.resource.AffinityPolicy - version: 1.0.0 - type_version: 1.0.0 - name: OSDF_CASABLANCA.Affinity_Default_vCPE_US_0 - metadata: - policy-id: OSDF_CASABLANCA.Affinity_Default_vCPE_US_0 - policy-version: 1 - properties: - scope: [] - services: [vCPE] - resources: [] - geography: [US] - identity: affinity_vCPE - applicableResources: any - affinityProperties: - qualifier: different - category: complex - - - OSDF_CASABLANCA.Affinity_vCPE_US_Gold_1: - type: onap.policies.optimization.resource.AffinityPolicy - version: 1.0.0 - type_version: 1.0.0 - name: OSDF_CASABLANCA.Affinity_vCPE_US_Gold_1 - metadata: - policy-id: OSDF_CASABLANCA.Affinity_vCPE_1 - policy-version: 1 - properties: - scope: [gold] - services: [vCPE] - resources: [vGMuxInfra, vG] - geography: [US, INTERNATIONAL] - identity: affinity_vCPE - applicableResources: any - affinityProperties: - qualifier: same - category: availabilityZone - - - OSDF_CASABLANCA.Affinity_vCPE_US_Platinum_1: - type: onap.policies.optimization.resource.AffinityPolicy - version: 1.0.0 - type_version: 1.0.0 - name: OSDF_CASABLANCA.Affinity_vCPE_US_Platinum_1 - metadata: - policy-id: OSDF_CASABLANCA.Affinity_vCPE_1 - policy-version: 1 - properties: - scope: [platinum] - services: [vCPE] - resources: [vGMuxInfra, vG] - geography: [US, INTERNATIONAL] - identity: affinity_vCPE - applicableResources: any - affinityProperties: - qualifier: different - category: availabilityZone - - - OSDF_CASABLANCA.Capacity_vG_1: - type: onap.policies.optimization.resource.Vim_fit - version: 1.0.0 - type_version: 1.0.0 - name: OSDF_CASABLANCA.Capacity_vG_1 - metadata: - policy-id: OSDF_CASABLANCA.Capacity_vG_1 - policy-version: 1 - properties: - scope: [] - services: [vCPE] - resources: [vG] - geography: [US, INTERNATIONAL] - identity: capacity_vG - applicableResources: any - capacityProperty: - controller: multicloud - request: "{\"vCPU\": 10, \"Memory\": {\"quantity\": {\"get_param\": \"REQUIRED_MEM\"}, \"unit\": \"GB\"}, \"Storage\": {\"quantity\": {\"get_param\": \"REQUIRED_DISK\"}, \"unit\": \"GB\"}}" - - - OSDF_CASABLANCA.Capacity_vG_2: - type: onap.policies.optimization.resource.Vim_fit - version: 1.0.0 - type_version: 1.0.0 - name: OSDF_CASABLANCA.Capacity_vG_2 - metadata: - policy-id: OSDF_CASABLANCA.Capacity_vG_2 - policy-version: 1 - properties: - scope: [] - services: [vCPE] - resources: [vG] - geography: [US, INTERNATIONAL] - identity: capacity_vG - applicableResources: any - capacityProperty: - controller: multicloud - request: "{\"vCPU\": 15, \"Memory\": {\"quantity\": {\"get_param\": \"REQUIRED_MEM\"}, \"unit\": \"MB\"}, \"Storage\": {\"quantity\": {\"get_param\": \"REQUIRED_DISK\"}, \"unit\": \"GB\"}}" - - - OSDF_CASABLANCA.Distance_vG_1: - type: onap.policies.optimization.resource.DistancePolicy - version: 1.0.0 - type_version: 1.0.0 - name: OSDF_CASABLANCA.Distance_vG_1 - metadata: - policy-id: OSDF_CASABLANCA.Distance_vG_1 - policy-version: 1 - properties: - scope: [platinum] - services: [vCPE] - resources: [vG] - geography: [US, INTERNATIONAL] - identity: distance-vG - applicableResources: any - distanceProperties: - locationInfo: customer_loc - distance: - value: 1500 - operator: "<" - unit: km - - - OSDF_CASABLANCA.hpa_policy_Default: - type: onap.policies.optimization.resource.HpaPolicy - version: 1.0.0 - type_version: 1.0.0 - name: OSDF_CASABLANCA.hpa_policy_Default - metadata: - policy-id: OSDF_CASABLANCA.hpa_policy_Default - policy-version: 1 - properties: - scope: [] - services: [] - resources: [] - geography: [] - identity: hpa-vG - flavorFeatures: - - - id: vg_1 - type: vnfc - directives: - - type: flavor_directives - attributes: - - attribute_name: flavor_label_vm_01 - attribute_value: "" - flavorProperties: - - - hpa-feature: basicCapabilities - mandatory: True - architecture: generic - directives: [] - hpa-feature-attributes: - - hpa-attribute-key: numVirtualCpu - hpa-attribute-value: 8 - operator: ['>='] - unit: "" - - hpa-attribute-key: virtualMemSize - hpa-attribute-value: 6 - operator: ['<='] - unit: "" - - - hpa-feature: ovsDpdk - mandatory: False - architecture: generic - directives: [] - hpa-feature-attributes: - - hpa-attribute-key: dataProcessingAccelerationLibrary - hpa-attribute-value: ovsDpdk_version - operator: [=] - unit: "" - - - OSDF_CASABLANCA.hpa_policy_vG_1: - type: onap.policies.optimization.resource.HpaPolicy - version: 1.0.0 - type_version: 1.0.0 - name: OSDF_CASABLANCA.hpa_policy_vG_1 - metadata: - policy-id: OSDF_CASABLANCA.hpa_policy_vG_1 - policy-version: 1 - properties: - scope: [] - services: [vCPE, vOtherService] - resources: [vG] - geography: [] - identity: hpa-vG - flavorFeatures: - - - id: vg_1 - type: vnfc - directives: - - type: flavor_directives - attributes: - - attribute_name: flavor_label_vm_01 - attribute_value: "" - flavorProperties: - - - hpa-feature: basicCapabilities - mandatory: True - architecture: generic - directives: [] - hpa-feature-attributes: - - hpa-attribute-key: numVirtualCpu - hpa-attribute-value: 6 - operator: ['>='] - unit: "" - - hpa-attribute-key: virtualMemSize - hpa-attribute-value: 4 - operator: ['<='] - unit: "" - - - hpa-feature: ovsDpdk - mandatory: False - architecture: generic - directives: [] - hpa-feature-attributes: - - hpa-attribute-key: dataProcessingAccelerationLibrary - hpa-attribute-value: ovsDpdk_version - operator: [=] - unit: "" - - - OSDF_CASABLANCA.queryPolicy_vCPE: - type: onap.policies.optimization.service.QueryPolicy - version: 1.0.0 - type_version: 1.0.0 - name: OSDF_CASABLANCA.queryPolicy_vCPE - metadata: - policy-id: OSDF_CASABLANCA.queryPolicy_vCPE - policy-version: 1 - properties: - scope: [] - services: [vCPE] - geography: [US, INTERNATIONAL] - identity: vCPE_Query_Policy - queryProperties: - - - attribute: locationId - attribute_location: customerLocation - value: "" - - - attribute: id - attribute_location: "vpnInfo.vpnId" - value: "" - - - attribute: upstreamBW - attribute_location: "vpnInfo.upstreamBW" - value: "" - - - attribute: customerLatitude - attribute_location: customerLatitude - value: 1.1 - - - attribute: customerLongitude - attribute_location: customerLongitude - value: 2.2 - - - OSDF_CASABLANCA.SubscriberPolicy_v1: - type: onap.policies.optimization.service.SubscriberPolicy - version: 1.0.0 - type_version: 1.0.0 - name: OSDF_CASABLANCA.SubscriberPolicy_v1 - metadata: - policy-id: OSDF_CASABLANCA.SubscriberPolicy_v1 - policy-version: 1 - properties: - scope: [] - services: [vCPE] - identity: subscriber_vCPE - subscriberProperties: - subscriberName: [subscriber_x, subscriber_y] - subscriberRole: [platinum] - provStatus: [CAPPED] - - - OSDF_CASABLANCA.SubscriberPolicy_v2: - type: onap.policies.optimization.service.SubscriberPolicy - version: 1.0.0 - type_version: 1.0.0 - name: OSDF_CASABLANCA.SubscriberPolicy_v2 - metadata: - policy-id: OSDF_CASABLANCA.SubscriberPolicy_v2 - policy-version: 1 - properties: - scope: [] - services: [vCPE] - identity: subscriber_vCPE - subscriberProperties: - subscriberName: [subscriber_a, subscriber_b] - subscriberRole: [gold] - provStatus: [CAPPED] - - - OSDF_CASABLANCA.vnfPolicy_vG: - type: onap.policies.optimization.resource.VnfPolicy - version: 1.0.0 - type_version: 1.0.0 - name: OSDF_CASABLANCA.vnfPolicy_vG - metadata: - policy-id: OSDF_CASABLANCA.vnfPolicy_vG - policy-version: 1 - properties: - scope: [] - services: [vCPE] - resources: [vG] - geography: [US, INTERNATIONAL] - identity: vnf_vG - applicableResources: any - vnfProperties: - - - inventoryProvider: aai - serviceType: "" - inventoryType: cloudRegionId - customerId: "" - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.Match.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.Match.yaml deleted file mode 100644 index 88b870580..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.Match.yaml +++ /dev/null @@ -1,8 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.Match: - derived_from: tosca.policies.Root - version: 1.0.0 - name: onap.policies.Match - description: Base Policy Type for matchable Policies - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.Naming.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.Naming.yaml deleted file mode 100644 index bde730cd7..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.Naming.yaml +++ /dev/null @@ -1,102 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.Naming: - derived_from: tosca.policies.Root - version: 1.0.0 - name: onap.policies.Naming - description: Virtual policy node for naming - properties: - policy-instance-name: - type: string - naming-models: - type: list - entry_schema: - type: policy.data.naming-model-entity -data_types: - policy.data.naming-model-entity: - derived_from: tosca.datatypes.Root - properties: - nfRole: - type: string - required: false - metadata: - matchable: true - naming-type: - type: string - required: true - metadata: - matchable: true - naming-recipe: - type: string - required: true - name-operation: - type: string - required: false - naming-properties: - type: list - required: true - entry_schema: - type: policy.data.naming-property - policy.data.naming-property: - derived_from: tosca.datatypes.Root - properties: - property-name: - type: string - required: true - metadata: - matchable: true - property-value: - type: string - required: false - property-operation: - type: string - required: false - source-system: - type: string - required: false - source-endpoint: - type: string - required: false - increment-sequence: - type: policy.data.increment-sequence - required: false - policy.data.increment-sequence: - derived_from: tosca.datatypes.Root - properties: - scope: - type: list - required: true - entry_schema: - type: string - constraints: - - valid_values: - - CLOUD_REGION_ID - - LOCATION_CLLI - - VNF - - VM - - VFMODULE - - PRECEEDING - - TRAILING - - ENTIRETY - sequence-type: - type: string - require: true - entry_schema: - type: string - constraints: - - valid_values: - - numeric - - alpha-numeric - start-value: - type: string - required: true - max: - type: string - required: false - increment: - type: string - required: true - length: - type: string - required: true - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.Optimization.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.Optimization.yaml deleted file mode 100644 index 7fe0e59de..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.Optimization.yaml +++ /dev/null @@ -1,33 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.Optimization: - derived_from: tosca.policies.Root - version: 1.0.0 - name: onap.policies.Optimization - description: The base policy type for all policies that govern optimization - properties: - scope: - description: Scope for the policy - could be for a specific release. - type: list - metadata: - matchable: true - required: true - entry_schema: - type: string - geography: - description: One or more geographic regions - type: list - metadata: - matchable: true - required: true - entry_schema: - type: string - constraints: - - valid_values: - - US - - International - identity: - description: Used internally for identification - type: string - required: true - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.Common.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.Common.yaml deleted file mode 100644 index 3dc979220..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.Common.yaml +++ /dev/null @@ -1,28 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.controlloop.guard.Common: - derived_from: tosca.policies.Root - version: 1.0.0 - name: onap.policies.controlloop.guard.Common - description: | - This is the base Policy Type for Guard policies that guard the execution of Operational - Policies. - properties: - actor: - type: string - description: Specifies the Actor the guard applies to. - required: true - operation: - type: string - description: Specified the operation that the actor is performing the guard applies to. - required: true - timeRange: - type: tosca.datatypes.TimeInterval - description: | - An optional range of time during the day the guard policy is valid for. - required: false - id: - type: string - description: The Control Loop id this applies to. - required: false - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.common.Blacklist.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.common.Blacklist.yaml deleted file mode 100644 index f2b67e18f..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.common.Blacklist.yaml +++ /dev/null @@ -1,16 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.controlloop.guard.common.Blacklist: - derived_from: onap.policies.controlloop.guard.Common - type_version: 1.0.0 - version: 1.0.0 - name: onap.policies.controlloop.guard.common.Blacklist - description: Supports blacklist of entity id's from performing control loop actions on. - properties: - blacklist: - type: list - description: List of entity id's not allowed to have control loop operations on. - required: true - entry_schema: - type: string - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.common.Filter.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.common.Filter.yaml deleted file mode 100644 index ea8e92aaf..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.common.Filter.yaml +++ /dev/null @@ -1,66 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.controlloop.guard.common.Filter: - derived_from: onap.policies.controlloop.guard.Common - type_version: 1.0.0 - version: 1.0.0 - name: onap.policies.controlloop.guard.common.Filter - description: Supports filtering of A&AI entities such as vnf-id, type, service, geographic region, etc. - properties: - algorithm: - type: string - description: Designates the precendence of blacklist vs whitelist - required: true - default: blacklist-overrides - constraints: - - valid_values: ["blacklist-overrides", "whitelist-overrides"] - filters: - type: list - description: List of filters to be applied. - required: true - entry_schema: - type: onap.datatypes.guard.filter -data_types: - onap.datatypes.guard.filter: - derived_from: tosca.nodes.Root - properties: - field: - type: string - description: Name of the field to perform the filter on using the A&AI . syntax. - required: true - constraints: - - valid_values: - - generic-vnf.vnf-name - - generic-vnf.vnf-id - - generic-vnf.vnf-type - - generic-vnf.nf-naming-code - - vserver.vserver-id - - cloud-region.cloud-region-id - filter: - type: string - description: The filter value itself. For example, "RegionOne" "vFWCL*" - required: true - function: - type: string - description: The function applied to the filter. - required: true - constraints: - - valid_values: - - string-equal - - string-equal-ignore-case - - string-regexp-match - - string-contains - - string-greater-than - - string-greater-than-or-equal - - string-less-than - - string-less-than-or-equal - - string-starts-with - - string-ends-with - blacklist: - type: boolean - description: | - Indicates if the filter should be treated as a blacklist (true) - or whitelist (false). - required: true - default: true - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.common.FrequencyLimiter.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.common.FrequencyLimiter.yaml deleted file mode 100644 index 3e31ec218..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.common.FrequencyLimiter.yaml +++ /dev/null @@ -1,26 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.controlloop.guard.common.FrequencyLimiter: - derived_from: onap.policies.controlloop.guard.Common - type_version: 1.0.0 - version: 1.0.0 - name: onap.policies.controlloop.guard.common.FrequencyLimiter - description: Supports limiting the frequency of actions being taken by a Actor. - properties: - timeWindow: - type: integer - description: The time window to count the actions against. - required: true - timeUnits: - type: string - description: The units of time the window is counting. - required: true - constraints: - - valid_values: ["second", "minute", "hour", "day", "week", "month", "year"] - limit: - type: integer - description: The limit - required: true - constraints: - - greater_than: 0 - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.common.MinMax.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.common.MinMax.yaml deleted file mode 100644 index 8f93572bf..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.common.MinMax.yaml +++ /dev/null @@ -1,24 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.controlloop.guard.common.MinMax: - derived_from: onap.policies.controlloop.guard.Common - type_version: 1.0.0 - version: 1.0.0 - name: onap.policies.controlloop.guard.common.MinMax - description: | - Supports Min/Max number of entity for scaling operations. Although min and max fields are marked as not - required, you need to have at least one or the other. - properties: - target: - type: string - required: true - description: The target entity that has scaling restricted - min: - type: integer - required: false - description: The minimum instances of this entity - max: - type: integer - required: false - description: The maximum instances of this entity - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.coordination.FirstBlocksSecond.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.coordination.FirstBlocksSecond.yaml deleted file mode 100644 index eaeee605d..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.guard.coordination.FirstBlocksSecond.yaml +++ /dev/null @@ -1,27 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.controlloop.Guard: - derived_from: tosca.policies.Root - version: 1.0.0 - name: onap.policies.controlloop.Guard - description: Guard Policies for Control Loop Operational Policies - onap.policies.controlloop.guard.Coordination: - derived_from: onap.policies.controlloop.Guard - version: 1.0.0 - name: onap.policies.controlloop.guard.Coordination - description: Guard Policies for Control Loop Coordination - onap.policies.controlloop.guard.coordination.FirstBlocksSecond: - derived_from: onap.policies.controlloop.guard.Coordination - version: 1.0.0 - name: onap.policies.controlloop.guard.coordination.FirstBlocksSecond - description: Supports one Control Loop blocking another - properties: - controlLoop: - type: list - description: Specific Control Loops to which to apply this guard - required: true - constraint: - length: 2 - entry_schema: - type: string - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.operational.Common.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.operational.Common.yaml deleted file mode 100644 index 9b3b057b8..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.operational.Common.yaml +++ /dev/null @@ -1,143 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.controlloop.operational.Common: - derived_from: tosca.policies.Root - version: 1.0.0 - name: onap.policies.controlloop.operational.Common - description: | - Operational Policy for Control Loop execution. Originated in Frankfurt to support TOSCA Compliant - Policy Types. This does NOT support the legacy Policy YAML policy type. - properties: - id: - type: string - description: The unique control loop id. - required: true - timeout: - type: integer - description: | - Overall timeout for executing all the operations. This timeout should equal or exceed the total - timeout for each operation listed. - required: true - abatement: - type: boolean - description: Whether an abatement event message will be expected for the control loop from DCAE. - required: true - default: false - trigger: - type: string - description: Initial operation to execute upon receiving an Onset event message for the Control Loop. - required: true - operations: - type: list - description: List of operations to be performed when Control Loop is triggered. - required: true - entry_schema: - type: onap.datatype.controlloop.Operation - -data_types: - onap.datatype.controlloop.Target: - derived_from: tosca.datatypes.Root - description: Definition for a entity in A&AI to perform a control loop operation on - properties: - targetType: - type: string - description: Category for the target type - required: true - constraints: - - valid_values: [VNF, VM, VFMODULE, PNF] - entityIds: - type: map - description: | - Map of values that identify the resource. If none are provided, it is assumed that the - entity that generated the ONSET event will be the target. - required: false - metadata: - clamp_possible_values: ClampExecution:CSAR_RESOURCES - entry_schema: - type: string - - onap.datatype.controlloop.Actor: - derived_from: tosca.datatypes.Root - description: An actor/operation/target definition - properties: - actor: - type: string - description: The actor performing the operation. - required: true - metadata: - clamp_possible_values: Dictionary:DefaultActors,ClampExecution:CDS/actor - operation: - type: string - description: The operation the actor is performing. - metadata: - clamp_possible_values: Dictionary:DefaultOperations,ClampExecution:CDS/operation - required: true - target: - type: onap.datatype.controlloop.Target - description: The resource the operation should be performed on. - required: true - payload: - type: map - description: Name/value pairs of payload information passed by Policy to the actor - required: false - metadata: - clamp_possible_values: ClampExecution:CDS/payload - entry_schema: - type: string - - onap.datatype.controlloop.Operation: - derived_from: tosca.datatypes.Root - description: An operation supported by an actor - properties: - id: - type: string - description: Unique identifier for the operation - required: true - description: - type: string - description: A user-friendly description of the intent for the operation - required: false - operation: - type: onap.datatype.controlloop.Actor - description: The definition of the operation to be performed. - required: true - timeout: - type: integer - description: The amount of time for the actor to perform the operation. - required: true - retries: - type: integer - description: The number of retries the actor should attempt to perform the operation. - required: true - default: 0 - success: - type: string - description: Points to the operation to invoke on success. A value of "final_success" indicates and end to the operation. - required: false - default: final_success - failure: - type: string - description: Points to the operation to invoke on Actor operation failure. - required: false - default: final_failure - failure_timeout: - type: string - description: Points to the operation to invoke when the time out for the operation occurs. - required: false - default: final_failure_timeout - failure_retries: - type: string - description: Points to the operation to invoke when the current operation has exceeded its max retries. - required: false - default: final_failure_retries - failure_exception: - type: string - description: Points to the operation to invoke when the current operation causes an exception. - required: false - default: final_failure_exception - failure_guard: - type: string - description: Points to the operation to invoke when the current operation is blocked due to guard policy enforcement. - required: false - default: final_failure_guard - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.operational.common.Apex.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.operational.common.Apex.yaml deleted file mode 100644 index a0c5b2456..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.operational.common.Apex.yaml +++ /dev/null @@ -1,26 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.controlloop.operational.common.Apex: - derived_from: onap.policies.controlloop.operational.Common - type_version: 1.0.0 - version: 1.0.0 - name: onap.policies.controlloop.operational.common.Apex - description: Operational policies for Apex PDP - properties: - engineServiceParameters: - type: string - description: The engine parameters like name, instanceCount, policy implementation, parameters etc. - required: true - eventInputParameters: - type: string - description: The event input parameters. - required: true - eventOutputParameters: - type: string - description: The event output parameters. - required: true - javaProperties: - type: string - description: Name/value pairs of properties to be set for APEX if needed. - required: false - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.operational.common.Drools.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.operational.common.Drools.yaml deleted file mode 100644 index 69d73db58..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.controlloop.operational.common.Drools.yaml +++ /dev/null @@ -1,14 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.controlloop.operational.common.Drools: - derived_from: onap.policies.controlloop.operational.Common - type_version: 1.0.0 - version: 1.0.0 - name: onap.policies.controlloop.operational.common.Drools - description: Operational policies for Drools PDP - properties: - controllerName: - type: string - description: Drools controller properties - required: false - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.dcae-pm-mapper.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.dcae-pm-mapper.yaml deleted file mode 100644 index c50392eca..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.dcae-pm-mapper.yaml +++ /dev/null @@ -1,50 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.Monitoring: - derived_from: tosca.policies.Root - version: 1.0.0 - name: onap.policies.Monitoring - description: a base policy type for all policies that govern monitoring provisioning - onap.policies.monitoring.dcae-pm-mapper: - derived_from: onap.policies.Monitoring - version: 1.0.0 - properties: - pm-mapper-filter: - type: map - description: PM mapper filter on measInfo, measInfoId, measType, instanceId - entry_schema: - type: onap.datatypes.monitoring.pm-mapper-filter -data_types: - onap.datatypes.monitoring.pm-mapper-filter: - derived_from: tosca.datatypes.Root - properties: - filters: - type: list - description: Filter configuration - #default: [] - required: true - entry_schema: - type: onap.datatypes.monitoring.filters - onap.datatypes.monitoring.filters: - derived_from: tosca.datatypes.Root - properties: - pmDefVsn: - type: string - description: PM Dictionary version - required: true - nfType: - type: string - description: NF type - required: true - vendor: - type: string - description: Vendor name - required: true - measTypes: - type: list - description: Measurement types to collect - #default: [] - required: true - entry_schema: - type: string - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.dcae-pm-subscription-handler.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.dcae-pm-subscription-handler.yaml deleted file mode 100644 index 8ac9b7484..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.dcae-pm-subscription-handler.yaml +++ /dev/null @@ -1,132 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.Monitoring: - derived_from: tosca.policies.Root - version: 1.0.0 - name: onap.policies.Monitoring - description: a base policy type for all policies that govern monitoring provisioning - onap.policies.monitoring.dcae-pm-subscription-handler: - derived_from: onap.policies.Monitoring - version: 1.0.0 - properties: - subscription: - type: map - description: PM Subscription Handler Subscription - entry_schema: - type: onap.datatypes.monitoring.subscription -data_types: - onap.datatypes.monitoring.subscription: - derived_from: tosca.datatypes.Root - properties: - subscriptionName: - type: string - description: Name of the subscription - required: true - administrativeState: - type: string - description: State of the subscription - required: true - constraints: - - valid_values: - - LOCKED - - UNLOCKED - fileBasedGP: - type: integer - description: File based granularity period - required: true - fileLocation: - type: string - description: ROP file location - required: true - nfTypeModelInvariantId: - type: string - description: Network function invariant ID - required: true - nfFilter: - type: map - description: Network function filter - required: true - entry_schema: - type: onap.datatypes.monitoring.nfFilter - measurementGroups: - type: list - description: Measurement Groups - required: true - entry_schema: - type: onap.datatypes.monitoring.measurementGroups - onap.datatypes.monitoring.nfFilter: - derived_from: tosca.datatypes.Root - properties: - nfNames: - type: list - description: List of network functions - required: true - #default: [] - entry_schema: - type: string - swVersions: - type: list - description: List of software versions - required: true - #default: [] - entry_schema: - type: string - onap.datatypes.monitoring.measurementGroups: - derived_from: tosca.datatypes.Root - properties: - measurementGroup: - type: map - description: Measurement Group - required: true - entry_schema: - type: onap.datatypes.monitoring.measurementGroup - onap.datatypes.monitoring.measurementGroup: - derived_from: tosca.datatypes.Root - properties: - measurementTypes: - type: list - description: List of measurement types - required: true - #default: [] - entry_schema: - type: onap.datatypes.monitoring.measurementTypes - managedObjectDNsBasic: - type: list - description: List of managed object distinguished names - required: true - #default: [] - entry_schema: - type: onap.datatypes.monitoring.managedObjectDNsBasics - onap.datatypes.monitoring.measurementTypes: - derived_from: tosca.datatypes.Root - properties: - measurementType: - type: map - description: Measurement type object - required: true - entry_schema: - type: onap.datatypes.monitoring.measurementType - onap.datatypes.monitoring.measurementType: - derived_from: tosca.datatypes.Root - properties: - measurementType: - type: string - description: Measurement type - required: true - onap.datatypes.monitoring.managedObjectDNsBasics: - derived_from: tosca.datatypes.Root - properties: - managedObjectDNsBasic: - type: map - description: Managed object distinguished name object - required: true - entry_schema: - type: onap.datatypes.monitoring.managedObjectDNsBasic - onap.datatypes.monitoring.managedObjectDNsBasic: - derived_from: tosca.datatypes.Root - properties: - DN: - type: string - description: Managed object distinguished name - required: true - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.dcae-restconfcollector.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.dcae-restconfcollector.yaml deleted file mode 100644 index 58e60e98d..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.dcae-restconfcollector.yaml +++ /dev/null @@ -1,128 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.Monitoring: - derived_from: tosca.policies.Root - version: 1.0.0 - name: onap.policies.Monitoring - description: a base policy type for all policies that govern monitoring provisioning - onap.policies.monitoring.dcae-restconfcollector: - derived_from: onap.policies.Monitoring - version: 1.0.0 - properties: - rcc_policy: - type: list - description: RCC Policy JSON - entry_schema: - type: onap.datatypes.monitoring.rcc_policy -data_types: - onap.datatypes.monitoring.rcc_policy: - derived_from: tosca.datatypes.Root - properties: - controller_name: - type: string - description: Name of controller - required: true - controller_restapiUrl: - type: string - description: Controller's ip and port - required: true - controller_restapiUser: - type: string - description: Controller's username - required: true - controller_restapiPassword: - type: string - description: Controller's password - required: true - controller_accessTokenUrl: - type: string - description: URL to get access token - required: true - controller_accessTokenFile: - type: string - description: Access token file path - required: true - controller_accessTokenMethod: - type: string - description: Access token method POST/GET/PUT etc - required: true - constraints: - - valid_values: - - post - - get - - put - controller_subsMethod: - type: string - description: Subscription method POST/GET/PUT etc - required: true - default: post - constraints: - - valid_values: - - post - - get - - put - controller_subscriptionUrl: - type: string - description: URL to establish subscription - required: true - controller_disableSsl: - type: boolean - description: Option to disable ssl - required: true - default: true - event_details: - type: list - description: event details - required: true - entry_schema: - type: onap.datatypes.monitoring.rcc_event_details - onap.datatypes.monitoring.rcc_event_details: - derived_from: tosca.datatypes.Root - properties: - event_name: - type: string - description: event name - required: true - event_description: - type: string - description: description of event - required: false - event_sseventUrlEmbed: - type: boolean - description: Whether SSE url is embedded in subscription response - required: true - default: true - event_sseventsField: - type: string - description: Field name to access SSE url in subscription response - required: true - event_sseventsUrl: - type: string - description: Explicit SSE url - required: true - event_subscriptionTemplate: - type: string - description: Subscription template file path - required: true - event_unSubscriptionTemplate: - type: string - description: Unsubscription template file path - required: false - event_ruleId: - type: integer - description: Rule Id - required: false - modifyData: - type: boolean - description: Whether to modify the received SSE event - required: true - default: false - modifyMethod: - type: string - description: The java method name to modify data - required: false - userData: - type: string - description: The user specific data - required: false - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.dcaegen2.collectors.datafile.datafile-app-server.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.dcaegen2.collectors.datafile.datafile-app-server.yaml deleted file mode 100644 index 408e8cd00..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.dcaegen2.collectors.datafile.datafile-app-server.yaml +++ /dev/null @@ -1,19 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.Monitoring: - derived_from: tosca.policies.Root - description: a base policy type for all policies that govern monitoring provisioning - version: 1.0.0 - name: onap.policies.Monitoring - onap.policies.monitoring.dcaegen2.collectors.datafile.datafile-app-server: - derived_from: onap.policies.Monitoring - version: 1.0.0 - name: onap.policies.monitoring.dcaegen2.collectors.datafile.datafile-app-server - properties: - buscontroller_feed_publishing_endpoint: - type: string - description: DMAAP Bus Controller feed endpoint - datafile.policy: - type: string - description: datafile Policy JSON as string - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.tcagen2.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.tcagen2.yaml deleted file mode 100644 index 04026b323..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.monitoring.tcagen2.yaml +++ /dev/null @@ -1,161 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.Monitoring: - derived_from: tosca.policies.Root - version: 1.0.0 - name: onap.policies.Monitoring - description: a base policy type for all policies that govern monitoring provisioning - onap.policies.monitoring.tcagen2: - derived_from: onap.policies.Monitoring - version: 1.0.0 - name: onap.policies.monitoring.tcagen2 - properties: - tca.policy: - type: onap.datatypes.monitoring.tca_policy - description: TCA Policy JSON - required: true -data_types: - onap.datatypes.monitoring.metricsPerEventName: - derived_from: tosca.datatypes.Root - properties: - controlLoopSchemaType: - type: string - required: true - description: Specifies Control Loop Schema Type for the event Name e.g. VNF, VM - constraints: - - valid_values: - - VM - - VNF - eventName: - type: string - required: true - description: Event name to which thresholds need to be applied - policyName: - type: string - required: true - description: TCA Policy Scope Name - policyScope: - type: string - required: true - description: TCA Policy Scope - policyVersion: - type: string - required: true - description: TCA Policy Scope Version - thresholds: - type: list - required: true - description: Thresholds associated with eventName - entry_schema: - type: onap.datatypes.monitoring.thresholds - onap.datatypes.monitoring.tca_policy: - derived_from: tosca.datatypes.Root - properties: - domain: - type: string - required: true - description: Domain name to which TCA needs to be applied - default: measurementsForVfScaling - constraints: - - equal: measurementsForVfScaling - metricsPerEventName: - type: list - required: true - description: Contains eventName and threshold details that need to be applied to given eventName - entry_schema: - type: onap.datatypes.monitoring.metricsPerEventName - onap.datatypes.monitoring.thresholds: - derived_from: tosca.datatypes.Root - properties: - closedLoopControlName: - type: string - required: true - description: Closed Loop Control Name associated with the threshold - closedLoopEventStatus: - type: string - required: true - description: Closed Loop Event Status of the threshold - constraints: - - valid_values: - - ONSET - - ABATED - direction: - type: string - required: true - description: Direction of the threshold - constraints: - - valid_values: - - LESS - - LESS_OR_EQUAL - - GREATER - - GREATER_OR_EQUAL - - EQUAL - fieldPath: - type: string - required: true - description: Json field Path as per CEF message which needs to be analyzed for TCA - constraints: - - valid_values: - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedTotalPacketsDelta - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedOctetsDelta - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedUnicastPacketsDelta - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedMulticastPacketsDelta - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedBroadcastPacketsDelta - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedDiscardedPacketsDelta - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedErrorPacketsDelta - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedTotalPacketsAccumulated - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedOctetsAccumulated - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedUnicastPacketsAccumulated - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedMulticastPacketsAccumulated - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedBroadcastPacketsAccumulated - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedDiscardedPacketsAccumulated - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedErrorPacketsAccumulated - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedTotalPacketsDelta - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedOctetsDelta - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedUnicastPacketsDelta - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedMulticastPacketsDelta - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedBroadcastPacketsDelta - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedDiscardedPacketsDelta - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedErrorPacketsDelta - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedTotalPacketsAccumulated - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedOctetsAccumulated - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedUnicastPacketsAccumulated - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedMulticastPacketsAccumulated - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedBroadcastPacketsAccumulated - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedDiscardedPacketsAccumulated - - $.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedErrorPacketsAccumulated - - $.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuIdle - - $.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuUsageInterrupt - - $.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuUsageNice - - $.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuUsageSoftIrq - - $.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuUsageSteal - - $.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuUsageSystem - - $.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuWait - - $.event.measurementsForVfScalingFields.cpuUsageArray[*].percentUsage - - $.event.measurementsForVfScalingFields.meanRequestLatency - - $.event.measurementsForVfScalingFields.memoryUsageArray[*].memoryBuffered - - $.event.measurementsForVfScalingFields.memoryUsageArray[*].memoryCached - - $.event.measurementsForVfScalingFields.memoryUsageArray[*].memoryConfigured - - $.event.measurementsForVfScalingFields.memoryUsageArray[*].memoryFree - - $.event.measurementsForVfScalingFields.memoryUsageArray[*].memoryUsed - - $.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value - severity: - type: string - required: true - description: Threshold Event Severity - constraints: - - valid_values: - - CRITICAL - - MAJOR - - MINOR - - WARNING - - NORMAL - thresholdValue: - type: integer - required: true - description: Threshold value for the field Path inside CEF message - version: - type: string - required: true - description: Version number associated with the threshold - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.native.Apex.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.native.Apex.yaml deleted file mode 100644 index d2a7632f3..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.native.Apex.yaml +++ /dev/null @@ -1,203 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.Native: - derived_from: tosca.policies.Root - description: a base policy type for all native PDP policies - version: 1.0.0 - name: onap.policies.Native - onap.policies.native.Apex: - derived_from: onap.policies.Native - description: a policy type for native apex policies - version: 1.0.0 - name: onap.policies.native.Apex - properties: - engine_service: - type: onap.datatypes.native.apex.EngineService - description: APEX Engine Service Parameters - inputs: - type: map - description: Inputs for handling events coming into the APEX engine - entry_schema: - type: onap.datatypes.native.apex.EventHandler - outputs: - type: map - description: Outputs for handling events going out of the APEX engine - entry_schema: - type: onap.datatypes.native.apex.EventHandler - environment: - type: list - description: Envioronmental parameters for the APEX engine - entry_schema: - type: onap.datatypes.native.apex.Environment - -data_types: - onap.datatypes.native.apex.EngineService: - derived_from: tosca.datatypes.Root - properties: - name: - type: string - description: Specifies the engine name - required: false - default: "ApexEngineService" - version: - type: string - description: Specifies the engine version in double dotted format - required: false - default: "1.0.0" - id: - type: integer - description: Specifies the engine id - required: true - instance_count: - type: integer - description: Specifies the number of engine threads that should be run - required: true - deployment_port: - type: integer - description: Specifies the port to connect to for engine administration - required: false - default: 1 - policy_model_file_name: - type: string - description: The name of the file from which to read the APEX policy model - required: false - policy_type_impl: - type: string - description: The policy type implementation from which to read the APEX policy model - required: false - periodic_event_period: - type: string - description: The time interval in milliseconds for the periodic scanning event, 0 means don't scan - required: false - engine: - type: onap.datatypes.native.apex.engineservice.Engine - description: The parameters for all engines in the APEX engine service - required: true - onap.datatypes.native.apex.EventHandler: - derived_from: tosca.datatypes.Root - properties: - name: - type: string - description: Specifies the event handler name, if not specified this is set to the key name - required: false - carrier_technology: - type: onap.datatypes.native.apex.CarrierTechnology - description: Specifies the carrier technology of the event handler (such as REST/Web Socket/Kafka) - required: true - event_protocol: - type: onap.datatypes.native.apex.EventProtocol - description: Specifies the event protocol of events for the event handler (such as Yaml/JSON/XML/POJO) - required: true - event_name: - type: string - description: Specifies the event name for events on this event handler, if not specified, the event name is read from or written to the event being received or sent - required: false - event_name_filter: - type: string - description: Specifies a filter as a regular expression, events that do not match the filter are dropped, the default is to let all events through - required: false - synchronous_mode: - type: boolean - description: Specifies the event handler is syncronous (receive event and send response) - required: false - default: false - synchronous_peer: - type: string - description: The peer event handler (output for input or input for output) of this event handler in synchronous mode, this parameter is mandatory if the event handler is in synchronous mode - required: false - synchronous_timeout: - type: integer - description: The timeout in milliseconds for responses to be issued by APEX torequests, this parameter is mandatory if the event handler is in synchronous mode - required: false - requestor_mode: - type: boolean - description: Specifies the event handler is in requestor mode (send event and wait for response mode) - required: false - default: false - requestor_peer: - type: string - description: The peer event handler (output for input or input for output) of this event handler in requestor mode, this parameter is mandatory if the event handler is in requestor mode - required: false - requestor_timeout: - type: integer - description: The timeout in milliseconds for wait for responses to requests, this parameter is mandatory if the event handler is in requestor mode - required: false - onap.datatypes.native.apex.CarrierTechnology: - derived_from: tosca.datatypes.Root - properties: - label: - type: string - description: The label (name) of the carrier technology (such as REST, Kafka, WebSocket) - required: true - plugin_parameter_class_name: - type: string - description: The class name of the class that overrides default handling of event input or output for this carrier technology, defaults to the supplied input or output class - required: false - onap.datatypes.native.apex.EventProtocol: - derived_from: tosca.datatypes.Root - properties: - label: - type: string - description: The label (name) of the event protocol (such as Yaml, JSON, XML, or POJO) - required: true - event_protocol_plugin_class: - type: string - description: The class name of the class that overrides default handling of the event protocol for this carrier technology, defaults to the supplied event protocol class - required: false - onap.datatypes.native.apex.Environment: - derived_from: tosca.datatypes.Root - properties: - name: - type: string - description: The name of the environment variable - required: true - value: - type: string - description: The value of the environment variable - required: true - onap.datatypes.native.apex.engineservice.Engine: - derived_from: tosca.datatypes.Root - properties: - context: - type: onap.datatypes.native.apex.engineservice.engine.Context - description: The properties for handling context in APEX engines, defaults to using Java maps for context - required: false - executors: - type: map - description: The plugins for policy executors used in engines such as javascript, MVEL, Jython - required: true - entry_schema: - description: The plugin class path for this policy executor - type: string - onap.datatypes.native.apex.engineservice.engine.Context: - derived_from: tosca.datatypes.Root - properties: - distributor: - type: onap.datatypes.native.apex.Plugin - description: The plugin to be used for distributing context between APEX PDPs at runtime - required: false - schemas: - type: map - description: The plugins for context schemas available in APEX PDPs such as Java and Avro - required: false - entry_schema: - type: onap.datatypes.native.apex.Plugin - locking: - type: onap.datatypes.native.apex.Plugin - description: The plugin to be used for locking context in and between APEX PDPs at runtime - required: false - persistence: - type: onap.datatypes.native.apex.Plugin - description: The plugin to be used for persisting context for APEX PDPs at runtime - required: false - onap.datatypes.native.apex.Plugin: - derived_from: tosca.datatypes.Root - properties: - name: - type: string - description: The name of the executor such as Javascript, Jython or MVEL - required: true - plugin_class_name: - type: string - description: The class path of the plugin class for this executor - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.native.Drools.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.native.Drools.yaml deleted file mode 100644 index 0ae96dbc2..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.native.Drools.yaml +++ /dev/null @@ -1,118 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.Native: - derived_from: tosca.policies.Root - description: a base policy type for all native PDP policies - version: 1.0.0 - name: onap.policies.Native - onap.policies.native.Drools: - derived_from: onap.policies.Native - description: a base policy type for all native PDP policies - version: 1.0.0 - name: onap.policies.native.Drools - onap.policies.native.drools.Controller: - derived_from: onap.policies.native.Drools - description: a policy type for a drools controller configuration - version: 1.0.0 - name: onap.policies.native.drools.Controller - properties: - controllerName: - type: string - required: true - description: the drools controller name - sourceTopics: - type: list - required: false - description: source topics and applicable events - entry_schema: - type: onap.datatypes.dmaap.topic - sinkTopics: - type: list - required: false - description: sink topics and applicable events - entry_schema: - type: onap.datatypes.dmaap.topic - customConfig: - type: map - required: false - description: any use case specific configurations relevant to the drools controller - entry_schema: - type: string - onap.policies.native.drools.Artifact: - derived_from: onap.policies.native.Drools - description: a policy type for native drools artifact policies - version: 1.0.0 - name: onap.policies.native.drools.Artifact - properties: - rulesArtifact: - type: onap.datatypes.native.rules_artifact - required: true - description: the GAV information of the maven artifact - controller: - type: onap.datatypes.drools.controller.relation - required: true - description: the drools controller to which the current native policy is assigned - -data_types: - onap.datatypes.dmaap.topic: - derived_from: tosca.datatypes.Root - properties: - topicName: - type: string - required: true - description: the dmaap topic name - events: - type: list - required: true - description: events used by this topic - entry_schema: - type: onap.datatypes.dmaap.events - onap.datatypes.dmaap.events: - derived_from: tosca.datatypes.Root - properties: - eventClass: - type: string - required: true - description: the event canonical class for serialization - eventFilter: - type: string - required: false - description: the JSONPath based condition to filter out the events to serialize - customSerialization: - type: onap.datatypes.dmaap.custom_serialization - required: false - description: overrides the default serialization/deserialization mechanisms with custom ones - onap.datatypes.dmaap.custom_serialization: - derived_from: tosca.datatypes.Root - properties: - customSerializerClass: - type: string - required: true - description: the class that contains the JSON parser serializer/deserializer. - jsonParser: - type: string - required: true - description: static field in customSerialized class with the json parser (currently only gson supported) - onap.datatypes.native.rules_artifact: - derived_from: tosca.datatypes.Root - properties: - groupId: - type: string - required: true - description: the groupId of the maven artifact - artifactId: - type: string - required: true - description: the artifactId of the maven artifact - version: - type: string - required: true - description: the version of the maven artifact - onap.datatypes.drools.controller.relation: - derived_from: tosca.datatypes.Root - properties: - name: - type: string - required: true - description: the name of drools controller policy - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.native.Xacml.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.native.Xacml.yaml deleted file mode 100644 index eb25cdb91..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.native.Xacml.yaml +++ /dev/null @@ -1,20 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.Native: - derived_from: tosca.policies.Root - description: a base policy type for all native PDP policies - version: 1.0.0 - name: onap.policies.Native - onap.policies.native.Xacml: - derived_from: onap.policies.Native - description: a policy type for native xacml policies - version: 1.0.0 - name: onap.policies.native.Xacml - properties: - policy: - type: string - required: true - description: The XML XACML 3.0 PolicySet or Policy - metadata: - encoding: Base64 - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.Resource.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.Resource.yaml deleted file mode 100644 index 6b3a2460d..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.Resource.yaml +++ /dev/null @@ -1,25 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.optimization.Resource: - derived_from: onap.policies.Optimization - version: 1.0.0 - name: onap.policies.optimization.Resource - description: The base policy type for all policies that govern optimization for a Resource in a Service. - properties: - services: - description: One or more services that the policy applies to. - type: list - metadata: - matchable: true - required: true - entry_schema: - type: string - resources: - description: One or more VNF resources that the policy applies to. - type: list - metadata: - matchable: true - required: true - entry_schema: - type: string - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.Service.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.Service.yaml deleted file mode 100644 index 8b37a67e7..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.Service.yaml +++ /dev/null @@ -1,17 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.optimization.Service: - derived_from: onap.policies.Optimization - version: 1.0.0 - name: onap.policies.optimization.Service - description: The base policy type for all policies that govern optimization for a Service. - properties: - services: - description: One or more services that the policy applies to. - type: list - metadata: - matchable: true - required: true - entry_schema: - type: string - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.AffinityPolicy.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.AffinityPolicy.yaml deleted file mode 100644 index bb6adb0aa..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.AffinityPolicy.yaml +++ /dev/null @@ -1,33 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.optimization.resource.AffinityPolicy: - derived_from: onap.policies.optimization.Resource - version: 1.0.0 - name: onap.policies.optimization.resource.AffinityPolicy - properties: - applicableResources: - type: list - required: true - entry_schema: - type: string - constraints: - - valid_values: - - any - - all - affinityProperties: - type: policy.data.affinityProperties_properties - required: true -data_types: - policy.data.affinityProperties_properties: - derived_from: tosca.nodes.Root - properties: - qualifier: - type: string - constraints: - - valid_values: - - same - - different - category: - type: string - required: true - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.DistancePolicy.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.DistancePolicy.yaml deleted file mode 100644 index f41dcfd6f..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.DistancePolicy.yaml +++ /dev/null @@ -1,58 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.optimization.resource.DistancePolicy: - derived_from: onap.policies.optimization.Resource - version: 1.0.0 - name: onap.policies.optimization.resource.DistancePolicy - properties: - applicableResources: - type: list - required: true - entry_schema: - type: string - constraints: - - valid_values: - - any - - all - distanceProperties: - type: policy.data.distanceProperties_properties - required: true -data_types: - policy.data.distanceProperties_properties: - derived_from: tosca.nodes.Root - properties: - locationInfo: - type: string - required: true - distance: - type: policy.data.distance_properties - required: true - entry_schema: - type: policy.data.distance_properties - policy.data.distance_properties: - derived_from: tosca.nodes.Root - properties: - value: - type: string - required: true - operator: - type: list - required: true - entry_schema: - type: string - constraints: - - valid_values: - - < - - <= - - '>' - - '>=' - - = - unit: - type: list - required: true - entry_schema: - type: string - constraints: - - valid_values: - - km - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.HpaPolicy.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.HpaPolicy.yaml deleted file mode 100644 index dfe30774b..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.HpaPolicy.yaml +++ /dev/null @@ -1,105 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.optimization.resource.HpaPolicy: - derived_from: onap.policies.optimization.Resource - version: 1.0.0 - name: onap.policies.optimization.resource.HpaPolicy - properties: - flavorFeatures: - type: list - required: true - entry_schema: - type: policy.data.flavorFeatures_properties -data_types: - policy.data.flavorFeatures_properties: - derived_from: tosca.nodes.Root - properties: - id: - type: string - required: true - type: - type: string - required: true - directives: - type: list - required: true - entry_schema: - type: policy.data.directives_properties - flavorProperties: - type: list - required: true - entry_schema: - type: policy.data.flavorProperties_properties - policy.data.directives_properties: - derived_from: tosca.nodes.Root - properties: - type: - type: string - attributes: - type: list - entry_schema: - type: policy.data.directives_attributes_properties - policy.data.directives_attributes_properties: - derived_from: tosca.nodes.Root - properties: - attribute_name: - type: string - attribute_value: - type: string - policy.data.flavorProperties_properties: - derived_from: tosca.nodes.Root - properties: - hpa-feature: - type: string - required: true - mandatory: - type: string - required: true - score: - type: string - required: false - architecture: - type: string - required: true - hpa-version: - type: string - required: true - directives: - type: list - required: true - entry_schema: - type: policy.data.directives_properties - hpa-feature-attributes: - type: list - required: true - entry_schema: - type: policy.data.hpa-feature-attributes_properties - policy.data.hpa-feature-attributes_properties: - derived_from: tosca.nodes.Root - properties: - hpa-attribute-key: - type: string - required: true - hpa-attribute-value: - type: string - required: true - operator: - type: list - required: true - entry_schema: - type: string - constraints: - - valid_values: - - < - - <= - - '>' - - '>=' - - = - - '!=' - - any - - all - - subset - unit: - type: string - required: false - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.OptimizationPolicy.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.OptimizationPolicy.yaml deleted file mode 100644 index b0f77d67e..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.OptimizationPolicy.yaml +++ /dev/null @@ -1,68 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.optimization.resource.OptimizationPolicy: - derived_from: onap.policies.optimization.Resource - version: 1.0.0 - name: onap.policies.optimization.resource.OptimizationPolicy - properties: - objective: - type: list - required: true - entry_schema: - type: string - constraints: - - valid_values: - - minimize - - maximize - objectiveParameter: - type: policy.data.objectiveParameter_properties - required: true -data_types: - policy.data.objectiveParameter_properties: - derived_from: tosca.nodes.Root - properties: - parameterAttributes: - type: list - required: true - entry_schema: - type: policy.data.parameterAttributes_properties - operator: - type: list - required: true - entry_schema: - type: string - constraints: - - valid_values: - - '*' - - + - - '-' - - / - - '%' - policy.data.parameterAttributes_properties: - derived_from: tosca.nodes.Root - properties: - resources: - type: string - required: true - customerLocationInfo: - type: string - required: true - parameter: - type: string - required: true - weight: - type: string - required: true - operator: - type: list - required: true - entry_schema: - type: string - constraints: - - valid_values: - - '*' - - + - - '-' - - / - - '%' - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.PciPolicy.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.PciPolicy.yaml deleted file mode 100644 index e636582df..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.PciPolicy.yaml +++ /dev/null @@ -1,32 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.optimization.resource.PciPolicy: - derived_from: onap.policies.optimization.Resource - version: 1.0.0 - name: onap.policies.optimization.resource.PciPolicy - properties: - pciProperties: - type: list - required: false - entry_schema: - type: policy.data.pciProperties_properties -data_types: - policy.data.pciProperties_properties: - derived_from: tosca.nodes.Root - properties: - algoCategory: - type: string - required: false - pciOptmizationAlgoName: - type: string - required: false - pciOptimizationNwConstraint: - type: string - required: false - pciOptimizationPriority: - type: string - required: false - pciOptimizationTimeConstraint: - type: string - required: false - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.Vim_fit.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.Vim_fit.yaml deleted file mode 100644 index cb387dda1..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.Vim_fit.yaml +++ /dev/null @@ -1,30 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.optimization.resource.Vim_fit: - derived_from: onap.policies.optimization.Resource - version: 1.0.0 - name: onap.policies.optimization.resource.Vim_fit - properties: - applicableResources: - type: list - required: true - entry_schema: - type: string - constraints: - - valid_values: - - any - - all - capacityProperties: - type: policy.data.capacityProperties_properties - required: true -data_types: - policy.data.capacityProperties_properties: - derived_from: tosca.nodes.Root - properties: - controller: - type: string - required: true - request: - type: string - required: true - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.VnfPolicy.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.VnfPolicy.yaml deleted file mode 100644 index 30b8b7212..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.resource.VnfPolicy.yaml +++ /dev/null @@ -1,46 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.optimization.resource.VnfPolicy: - derived_from: onap.policies.optimization.Resource - version: 1.0.0 - name: onap.policies.optimization.resource.VnfPolicy - properties: - applicableResources: - type: list - required: true - entry_schema: - type: string - constraints: - - valid_values: - - any - - all - vnfProperties: - type: list - required: true - entry_schema: - type: policy.data.vnfProperties_properties -data_types: - policy.data.vnfProperties_properties: - derived_from: tosca.nodes.Root - properties: - inventoryProvider: - type: string - required: true - serviceType: - type: string - required: true - inventoryType: - type: list - required: true - entry_schema: - type: string - constraints: - - valid_values: - - serviceInstanceId - - vnfName - - cloudRegionId - - vimId - customerId: - type: string - required: true - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.service.QueryPolicy.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.service.QueryPolicy.yaml deleted file mode 100644 index 2ff263b24..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.service.QueryPolicy.yaml +++ /dev/null @@ -1,26 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.optimization.service.QueryPolicy: - derived_from: onap.policies.optimization.Service - version: 1.0.0 - name: onap.policies.optimization.service.QueryPolicy - properties: - queryProperties: - type: list - required: true - entry_schema: - type: policy.data.queryProperties_properties -data_types: - policy.data.queryProperties_properties: - derived_from: tosca.nodes.Root - properties: - attribute: - type: string - required: true - value: - type: string - required: true - attribute_location: - type: string - required: true - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.service.SubscriberPolicy.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.service.SubscriberPolicy.yaml deleted file mode 100644 index 81dea2c3c..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/policytypes/onap.policies.optimization.service.SubscriberPolicy.yaml +++ /dev/null @@ -1,36 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.optimization.service.SubscriberPolicy: - derived_from: onap.policies.optimization.Service - version: 1.0.0 - name: onap.policies.optimization.service.SubscriberPolicy - properties: - subscriberProperties: - type: policy.data.subscriberProperties_properties - required: true -data_types: - policy.data.subscriberProperties_properties: - derived_from: tosca.nodes.Root - properties: - subscriberName: - type: list - required: true - metadata: - contextProvider: true - entry_schema: - type: string - subscriberRole: - type: list - required: true - metadata: - contextMatchable: scope - entry_schema: - type: string - provStatus: - type: list - required: true - metadata: - contextAttribute: true - entry_schema: - type: string - diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/utils/servicetemplates/pm_automation_composition_tosca.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/utils/servicetemplates/pm_automation_composition_tosca.yaml new file mode 100644 index 000000000..3d14cf572 --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/test/resources/utils/servicetemplates/pm_automation_composition_tosca.yaml @@ -0,0 +1,164 @@ +tosca_definitions_version: tosca_simple_yaml_1_3 +data_types: + onap.datatypes.ToscaConceptIdentifier: + derived_from: tosca.datatypes.Root + properties: + name: + type: string + required: true + version: + type: string + required: true +node_types: + org.onap.policy.clamp.acmParticipant: + version: 1.0.1 + derived_from: tosca.nodetypes.Root + properties: + provider: + type: string + requred: false + org.onap.policy.clamp.acmAutomationCompositionElement: + version: 1.0.1 + derived_from: tosca.nodetypes.Root + properties: + provider: + type: string + requred: false + participantType: + type: onap.datatypes.ToscaConceptIdentifier + requred: true + startPhase: + type: integer + required: false + constraints: + - greater-or-equal: 0 + metadata: + common: true + description: A value indicating the start phase in which this automation composition element will be started, + the first start phase is zero. Automation Composition Elements are started in their start_phase + order and stopped in reverse start phase order. Automation Composition Elements with the same start + phase are started and stopped simultaneously + org.onap.policy.clamp.acmAutomationComposition: + version: 1.0.1 + derived_from: tosca.nodetypes.Root + properties: + provider: + type: string + requred: false + elements: + type: list + required: true + entry_schema: + type: onap.datatypes.ToscaConceptIdentifier + org.onap.policy.clamp.acmDCAEMicroserviceAutomationCompositionElement: + version: 1.0.1 + derived_from: org.onap.policy.clamp.acmAutomationCompositionElement + properties: + dcae_blueprint_id: + type: onap.datatypes.ToscaConceptIdentifier + requred: true + org.onap.policy.clamp.acmPolicyTypeAutomationCompositionElement: + version: 1.0.1 + derived_from: org.onap.policy.clamp.acmAutomationCompositionElement + properties: + policy_type_id: + type: onap.datatypes.ToscaConceptIdentifier + requred: true + org.onap.policy.clamp.acmCDSAutomationCompositionElement: + version: 1.0.1 + derived_from: org.onap.policy.clamp.acmAutomationCompositionElement + properties: + cds_blueprint_id: + type: onap.datatypes.ToscaConceptIdentifier + requred: true +topology_template: + node_templates: + org.onap.dcae.acmDCAEMicroserviceAutomationCompositionParticipant: + version: 2.3.4 + type: org.onap.policy.clamp.acmParticipant + type_version: 1.0.1 + description: Participant for DCAE microservices + properties: + provider: ONAP + org.onap.policy.acmPolicyAutomationCompositionParticipant: + version: 2.3.1 + type: org.onap.policy.clamp.acmParticipant + type_version: 1.0.1 + description: Participant for DCAE microservices + properties: + provider: ONAP + org.onap.ccsdk.cds.acmCdsAutomationCompositionParticipant: + version: 2.2.1 + type: org.onap.policy.clamp.acmParticipant + type_version: 1.0.1 + description: Participant for DCAE microservices + properties: + provider: ONAP + org.onap.domain.pmsh.PMSH_DCAEMicroservice: + version: 1.2.3 + type: org.onap.policy.clamp.acmDCAEMicroserviceAutomationCompositionElement + type_version: 1.0.0 + description: Automation composition element for DCAE microservice for Performance Management Subscription Handling + properties: + provider: Ericsson + participantType: + name: org.onap.dcae.acmDCAEMicroserviceAutomationCompositionParticipant + version: 2.3.4 + dcae_blueprint_id: + name: org.onap.dcae.blueprints.PMSHBlueprint + version: 1.0.0 + org.onap.domain.pmsh.PMSH_MonitoringPolicyAutomationCompositionElement: + version: 1.2.3 + type: org.onap.policy.clamp.acmPolicyTypeAutomationCompositionElement + type_version: 1.0.0 + description: Automation composition element for monitoring policy for Performance Management Subscription Handling + properties: + provider: Ericsson + participantType: + name: org.onap.policy.acmPolicyAutomationCompositionParticipant + version: 2.3.1 + policy_type_id: + name: onap.policies.monitoring.pm-subscription-handler + version: 1.0.0 + org.onap.domain.pmsh.PMSH_OperationalPolicyAutomationCompositionElement: + version: 1.2.3 + type: org.onap.policy.clamp.acmPolicyTypeAutomationCompositionElement + type_version: 1.0.0 + description: Automation composition element, operational policy for Performance Management Subscription Handling + properties: + provider: Ericsson + participantType: + name: org.onap.policy.acmPolicyAutomationCompositionParticipant + version: 2.3.1 + policy_type_id: + name: onap.policies.operational.pm-subscription-handler + version: 1.0.0 + org.onap.domain.pmsh.PMSH_CDS_AutomationCompositionElement: + version: 1.2.3 + type: org.onap.policy.clamp.acmAutomationCompositionElement + type_version: 1.0.0 + description: Automation composition element for CDS for Performance Management Subscription Handling + properties: + provider: Ericsson + participantType: + name: org.onap.ccsdk.cds.acmCdsAutomationCompositionParticipant + version: 3.2.1 + cds_blueprint_id: + name: org.onap.ccsdk.cds.PMSHCdsBlueprint + version: 1.0.0 + org.onap.domain.pmsh.PMSHAutomationCompositionDefinition: + version: 1.2.3 + type: org.onap.policy.clamp.acmAutomationComposition + type_version: 1.0.0 + description: Automation composition for Performance Management Subscription Handling + properties: + provider: Ericsson + elements: + - name: org.onap.domain.pmsh.PMSH_DCAEMicroservice + version: 1.2.3 + - name: org.onap.domain.pmsh.PMSH_MonitoringPolicyAutomationCompositionElement + version: 1.2.3 + - name: org.onap.domain.pmsh.PMSH_OperationalPolicyAutomationCompositionElement + version: 1.2.3 + - name: org.onap.domain.pmsh.PMSH_CDS_AutomationCompositionElement + version: 1.2.3 diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/utils/servicetemplates/pm_control_loop_tosca.yaml b/participant/participant-impl/participant-impl-policy/src/test/resources/utils/servicetemplates/pm_control_loop_tosca.yaml deleted file mode 100644 index 33b42b7bc..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/utils/servicetemplates/pm_control_loop_tosca.yaml +++ /dev/null @@ -1,164 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_3 -data_types: - onap.datatypes.ToscaConceptIdentifier: - derived_from: tosca.datatypes.Root - properties: - name: - type: string - required: true - version: - type: string - required: true -node_types: - org.onap.policy.clamp.controlloop.Participant: - version: 1.0.1 - derived_from: tosca.nodetypes.Root - properties: - provider: - type: string - requred: false - org.onap.policy.clamp.controlloop.ControlLoopElement: - version: 1.0.1 - derived_from: tosca.nodetypes.Root - properties: - provider: - type: string - requred: false - participantType: - type: onap.datatypes.ToscaConceptIdentifier - requred: true - startPhase: - type: integer - required: false - constraints: - - greater-or-equal: 0 - metadata: - common: true - description: A value indicating the start phase in which this control loop element will be started, the - first start phase is zero. Control Loop Elements are started in their start_phase order and stopped - in reverse start phase order. Control Loop Elements with the same start phase are started and - stopped simultaneously - org.onap.policy.clamp.controlloop.ControlLoop: - version: 1.0.1 - derived_from: tosca.nodetypes.Root - properties: - provider: - type: string - requred: false - elements: - type: list - required: true - entry_schema: - type: onap.datatypes.ToscaConceptIdentifier - org.onap.policy.clamp.controlloop.DCAEMicroserviceControlLoopElement: - version: 1.0.1 - derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement - properties: - dcae_blueprint_id: - type: onap.datatypes.ToscaConceptIdentifier - requred: true - org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement: - version: 1.0.1 - derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement - properties: - policy_type_id: - type: onap.datatypes.ToscaConceptIdentifier - requred: true - org.onap.policy.clamp.controlloop.CDSControlLoopElement: - version: 1.0.1 - derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement - properties: - cds_blueprint_id: - type: onap.datatypes.ToscaConceptIdentifier - requred: true -topology_template: - node_templates: - org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant: - version: 2.3.4 - type: org.onap.policy.clamp.controlloop.Participant - type_version: 1.0.1 - description: Participant for DCAE microservices - properties: - provider: ONAP - org.onap.policy.controlloop.PolicyControlLoopParticipant: - version: 2.3.1 - type: org.onap.policy.clamp.controlloop.Participant - type_version: 1.0.1 - description: Participant for DCAE microservices - properties: - provider: ONAP - org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant: - version: 2.2.1 - type: org.onap.policy.clamp.controlloop.Participant - type_version: 1.0.1 - description: Participant for DCAE microservices - properties: - provider: ONAP - org.onap.domain.pmsh.PMSH_DCAEMicroservice: - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.DCAEMicroserviceControlLoopElement - type_version: 1.0.0 - description: Control loop element for the DCAE microservice for Performance Management Subscription Handling - properties: - provider: Ericsson - participantType: - name: org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant - version: 2.3.4 - dcae_blueprint_id: - name: org.onap.dcae.blueprints.PMSHBlueprint - version: 1.0.0 - org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement: - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement - type_version: 1.0.0 - description: Control loop element for the monitoring policy for Performance Management Subscription Handling - properties: - provider: Ericsson - participantType: - name: org.onap.policy.controlloop.PolicyControlLoopParticipant - version: 2.3.1 - policy_type_id: - name: onap.policies.monitoring.pm-subscription-handler - version: 1.0.0 - org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement: - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement - type_version: 1.0.0 - description: Control loop element for the operational policy for Performance Management Subscription Handling - properties: - provider: Ericsson - participantType: - name: org.onap.policy.controlloop.PolicyControlLoopParticipant - version: 2.3.1 - policy_type_id: - name: onap.policies.operational.pm-subscription-handler - version: 1.0.0 - org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement: - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.ControlLoopElement - type_version: 1.0.0 - description: Control loop element for CDS for Performance Management Subscription Handling - properties: - provider: Ericsson - participantType: - name: org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant - version: 3.2.1 - cds_blueprint_id: - name: org.onap.ccsdk.cds.PMSHCdsBlueprint - version: 1.0.0 - org.onap.domain.pmsh.PMSHControlLoopDefinition: - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.ControlLoop - type_version: 1.0.0 - description: Control loop for Performance Management Subscription Handling - properties: - provider: Ericsson - elements: - - name: org.onap.domain.pmsh.PMSH_DCAEMicroservice - version: 1.2.3 - - name: org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement - version: 1.2.3 - - name: org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement - version: 1.2.3 - - name: org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement - version: 1.2.3 diff --git a/participant/participant-impl/participant-impl-simulator/pom.xml b/participant/participant-impl/participant-impl-simulator/pom.xml index c19e45ee0..5673cb7c8 100644 --- a/participant/participant-impl/participant-impl-simulator/pom.xml +++ b/participant/participant-impl/participant-impl-simulator/pom.xml @@ -31,7 +31,7 @@ policy-clamp-participant-impl-simulator ${project.artifactId} - Participant simulator, used to test control loops + Participant simulator, used to test automation compositions diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/ParticipantSimulatorApplication.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/ParticipantSimulatorApplication.java new file mode 100644 index 000000000..ea94795fb --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/ParticipantSimulatorApplication.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.simulator; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.ConfigurationPropertiesScan; +import org.springframework.context.annotation.ComponentScan; + +/** + * Starter. + * + */ +// @formatter:off +@SpringBootApplication +@ConfigurationPropertiesScan("org.onap.policy.clamp.acm.participant.simulator.main.parameters") +@ComponentScan({ + "org.onap.policy.clamp.acm.participant.simulator", + "org.onap.policy.clamp.acm.participant.intermediary", + "org.onap.policy.clamp.acm.common.rest" +}) +//@formatter:on +public class ParticipantSimulatorApplication { + + public static void main(String[] args) { + SpringApplication.run(ParticipantSimulatorApplication.class, args); + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/AafConfiguration.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/AafConfiguration.java new file mode 100644 index 000000000..101e7fac2 --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/AafConfiguration.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. 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.onap.policy.clamp.acm.participant.simulator.config; + +import javax.servlet.Filter; +import org.onap.policy.clamp.acm.participant.simulator.main.rest.ParticipantSimulatorAafFilter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; + +@Configuration +@Profile("clamp-aaf-authentication") +public class AafConfiguration { + + /** + * Method to return Aaf filter. + * + * @return Filter + */ + @Bean + public Filter aafFilter() { + return new ParticipantSimulatorAafFilter(); + } + +} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/ParticipantConfig.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/ParticipantConfig.java new file mode 100644 index 000000000..92ced99d7 --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/ParticipantConfig.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.simulator.config; + +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.acm.participant.simulator.main.handler.AutomationCompositionElementHandler; +import org.onap.policy.clamp.common.acm.rest.RequestResponseLoggingFilter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ParticipantConfig { + + /** + * logging Filter configuration. + * + * @return FilterRegistrationBean + */ + @Bean + public FilterRegistrationBean loggingFilter() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + + registrationBean.setFilter(new RequestResponseLoggingFilter()); + registrationBean.addUrlPatterns("/onap/participantsim/v2/*"); + + return registrationBean; + } + + /** + * Register AutomationCompositionElementListener. + * + * @param intermediaryApi the ParticipantIntermediaryApi + * @param acElementHandler the AutomationComposition Element Handler + */ + @Autowired + public void registerAutomationCompositionElementListener(ParticipantIntermediaryApi intermediaryApi, + AutomationCompositionElementHandler acElementHandler) { + intermediaryApi.registerAutomationCompositionElementListener(acElementHandler); + acElementHandler.setIntermediaryApi(intermediaryApi); + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/SecurityConfig.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/SecurityConfig.java new file mode 100644 index 000000000..c41c6e1b3 --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/SecurityConfig.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.simulator.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.authorizeRequests() + .antMatchers().authenticated() + .anyRequest().authenticated() + .and().httpBasic().and().csrf().disable(); + // @formatter:on + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/SpringFoxConfig.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/SpringFoxConfig.java new file mode 100644 index 000000000..d9909818f --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/SpringFoxConfig.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.simulator.config; + +import org.onap.policy.clamp.acm.participant.simulator.simulation.rest.SimulationElementController; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; + +@Configuration +public class SpringFoxConfig { + + /** + * Docket Spring Fox Config. + * + * @return Docket + */ + @Bean + public Docket api() { + return new Docket(DocumentationType.SWAGGER_2).select() + .apis(RequestHandlerSelectors.basePackage(SimulationElementController.class.getPackageName())) + .paths(PathSelectors.any()).build(); + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/YamlConfiguration.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/YamlConfiguration.java new file mode 100644 index 000000000..718697786 --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/config/YamlConfiguration.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.simulator.config; + +import java.util.List; +import org.onap.policy.clamp.common.acm.rest.CoderHttpMesageConverter; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class YamlConfiguration implements WebMvcConfigurer { + + @Override + public void extendMessageConverters(List> converters) { + converters.add(new CoderHttpMesageConverter<>("yaml")); + converters.add(new CoderHttpMesageConverter<>("json")); + + StringHttpMessageConverter converter = new StringHttpMessageConverter(); + converter.setSupportedMediaTypes(List.of(MediaType.TEXT_PLAIN)); + converters.add(converter); + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/handler/AutomationCompositionElementHandler.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/handler/AutomationCompositionElementHandler.java new file mode 100644 index 000000000..9e30c8809 --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/handler/AutomationCompositionElementHandler.java @@ -0,0 +1,112 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.simulator.main.handler; + +import java.time.Instant; +import java.util.UUID; +import lombok.Setter; +import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener; +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.models.acm.concepts.AcElementStatistics; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * This class handles implementation of automationCompositionElement updates. + */ +@Component +public class AutomationCompositionElementHandler implements AutomationCompositionElementListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionElementHandler.class); + + @Setter + private ParticipantIntermediaryApi intermediaryApi; + + /** + * Callback method to handle a automation composition element state change. + * + * @param automationCompositionElementId the ID of the automation composition element + * @param currentState the current state of the automation composition element + * @param newState the state to which the automation composition element is changing to + * @throws PfModelException in case of an exception + */ + @Override + public void automationCompositionElementStateChange(ToscaConceptIdentifier automationCompositionId, + UUID automationCompositionElementId, AutomationCompositionState currentState, + AutomationCompositionOrderedState newState) throws PfModelException { + switch (newState) { + case UNINITIALISED: + intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, + automationCompositionElementId, newState, AutomationCompositionState.UNINITIALISED, + ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE); + break; + case PASSIVE: + intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, + automationCompositionElementId, newState, AutomationCompositionState.PASSIVE, + ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE); + break; + case RUNNING: + intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, + automationCompositionElementId, newState, AutomationCompositionState.RUNNING, + ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE); + break; + default: + LOGGER.debug("Unknown orderedstate {}", newState); + break; + } + } + + /** + * Callback method to handle an update on a automation composition element. + * + * @param element the information on the automation composition element + * @param acElementDefinition toscaNodeTemplate + * @throws PfModelException in case of an exception + */ + @Override + public void automationCompositionElementUpdate(ToscaConceptIdentifier automationCompositionId, + AutomationCompositionElement element, ToscaNodeTemplate acElementDefinition) throws PfModelException { + intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(), + element.getOrderedState(), AutomationCompositionState.PASSIVE, + ParticipantMessageType.AUTOMATION_COMPOSITION_UPDATE); + } + + @Override + public void handleStatistics(UUID automationCompositionElementId) throws PfModelException { + var acElement = intermediaryApi.getAutomationCompositionElement(automationCompositionElementId); + if (acElement != null) { + var acElementStatistics = new AcElementStatistics(); + acElementStatistics.setState(acElement.getState()); + acElementStatistics.setTimeStamp(Instant.now()); + intermediaryApi.updateAutomationCompositionElementStatistics(automationCompositionElementId, + acElementStatistics); + } + } + +} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/parameters/ParticipantSimulatorParameters.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/parameters/ParticipantSimulatorParameters.java new file mode 100644 index 000000000..8549e4c7b --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/parameters/ParticipantSimulatorParameters.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.simulator.main.parameters; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; +import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantIntermediaryParameters; +import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantParameters; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.validation.annotation.Validated; + +/** + * Class to hold all parameters needed for the participant simulator. + * + */ +@Validated +@Getter +@Setter +@ConfigurationProperties(prefix = "participant") +public class ParticipantSimulatorParameters implements ParticipantParameters { + + @Valid + @NotNull + private ParticipantIntermediaryParameters intermediaryParameters; +} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/AbstractRestController.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/AbstractRestController.java new file mode 100644 index 000000000..4db07c953 --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/AbstractRestController.java @@ -0,0 +1,130 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.simulator.main.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.BasicAuthDefinition; +import io.swagger.annotations.Info; +import io.swagger.annotations.SecurityDefinition; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import java.net.HttpURLConnection; +import java.util.UUID; +import javax.ws.rs.core.MediaType; +import lombok.AccessLevel; +import lombok.Getter; +import org.onap.policy.clamp.acm.participant.simulator.simulation.SimulationProvider; +import org.springframework.http.HttpHeaders; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * Common superclass to provide REST endpoints for the participant simulator. + */ +// @formatter:off +@RequestMapping( + value = "/v2", + produces = { + MediaType.APPLICATION_JSON, + AbstractRestController.APPLICATION_YAML + } +) +@Api(value = "Participant Simulator API") +@SwaggerDefinition( + info = @Info( + description = "Participant Simulator", + version = "v1.0", + title = "Participant Simulator" + ), + consumes = {MediaType.APPLICATION_JSON, AbstractRestController.APPLICATION_YAML}, + produces = {MediaType.APPLICATION_JSON, AbstractRestController.APPLICATION_YAML}, + schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS}, + tags = { + @Tag(name = "participantsim", description = "Participant Simulator") + }, + securityDefinition = @SecurityDefinition(basicAuthDefinitions = {@BasicAuthDefinition(key = "basicAuth")})) +// @formatter:on +public abstract class AbstractRestController { + public static final String APPLICATION_YAML = "application/yaml"; + + public static final String EXTENSION_NAME = "interface info"; + + public static final String API_VERSION_NAME = "api-version"; + public static final String API_VERSION = "1.0.0"; + + public static final String LAST_MOD_NAME = "last-mod-release"; + public static final String LAST_MOD_RELEASE = "Dublin"; + + public static final String VERSION_MINOR_NAME = "X-MinorVersion"; + public static final String VERSION_MINOR_DESCRIPTION = + "Used to request or communicate a MINOR version back from the client" + + " to the server, and from the server back to the client"; + + public static final String VERSION_PATCH_NAME = "X-PatchVersion"; + public static final String VERSION_PATCH_DESCRIPTION = "Used only to communicate a PATCH version in a response for" + + " troubleshooting purposes only, and will not be provided by" + " the client on request"; + + public static final String VERSION_LATEST_NAME = "X-LatestVersion"; + public static final String VERSION_LATEST_DESCRIPTION = "Used only to communicate an API's latest version"; + + public static final String REQUEST_ID_NAME = "X-ONAP-RequestID"; + public static final String REQUEST_ID_HDR_DESCRIPTION = "Used to track REST transactions for logging purpose"; + public static final String REQUEST_ID_PARAM_DESCRIPTION = "RequestID for http transaction"; + + public static final String AUTHORIZATION_TYPE = "basicAuth"; + + public static final int AUTHENTICATION_ERROR_CODE = HttpURLConnection.HTTP_UNAUTHORIZED; + public static final int AUTHORIZATION_ERROR_CODE = HttpURLConnection.HTTP_FORBIDDEN; + public static final int SERVER_ERROR_CODE = HttpURLConnection.HTTP_INTERNAL_ERROR; + + public static final String AUTHENTICATION_ERROR_MESSAGE = "Authentication Error"; + public static final String AUTHORIZATION_ERROR_MESSAGE = "Authorization Error"; + public static final String SERVER_ERROR_MESSAGE = "Internal Server Error"; + + // The provider for simulation requests + @Getter(AccessLevel.PROTECTED) + private SimulationProvider simulationProvider; + + /** + * create a Rest Controller. + * + * @param simulationProvider the provider for the simulation participant + */ + protected AbstractRestController(SimulationProvider simulationProvider) { + this.simulationProvider = simulationProvider; + } + + /** + * Get the common headers for responses. + * + * @param requestId the request ID + * + * @return the headers + */ + protected HttpHeaders getCommonHeaders(UUID requestId) { + HttpHeaders commonHeaders = new HttpHeaders(); + commonHeaders.add(VERSION_MINOR_NAME, API_VERSION.split("\\.")[1]); + commonHeaders.add(VERSION_PATCH_NAME, API_VERSION.split("\\.")[2]); + commonHeaders.add(VERSION_LATEST_NAME, API_VERSION); + commonHeaders.add(REQUEST_ID_NAME, (requestId != null ? requestId.toString() : null)); + + return commonHeaders; + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/GlobalControllerExceptionHandler.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/GlobalControllerExceptionHandler.java new file mode 100644 index 000000000..69714137f --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/GlobalControllerExceptionHandler.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.simulator.main.rest; + +import org.onap.policy.clamp.common.acm.exception.AutomationCompositionException; +import org.onap.policy.clamp.models.acm.messages.rest.SimpleResponse; +import org.onap.policy.clamp.models.acm.rest.RestUtils; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class GlobalControllerExceptionHandler { + + /** + * Handle AutomationCompositionException. + * + * @param ex AutomationCompositionException + * @return ResponseEntity + */ + @ExceptionHandler(AutomationCompositionException.class) + public ResponseEntity handleBadRequest(AutomationCompositionException ex) { + return RestUtils.toSimpleResponse(ex); + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/ParticipantErrorController.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/ParticipantErrorController.java new file mode 100644 index 000000000..e32c57254 --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/ParticipantErrorController.java @@ -0,0 +1,97 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.simulator.main.rest; + +import java.util.Map; +import javax.servlet.RequestDispatcher; +import javax.servlet.http.HttpServletRequest; +import org.onap.policy.clamp.models.acm.messages.rest.SimpleResponse; +import org.onap.policy.clamp.models.acm.messages.rest.TypedSimpleResponse; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.error.ErrorAttributeOptions; +import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.web.servlet.error.ErrorController; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.context.request.ServletWebRequest; + +@Controller +public class ParticipantErrorController implements ErrorController { + + private final ErrorAttributes errorAttributes; + + @Value("${server.error.path}") + private String path; + + /** + * Constructor. + * + * @param errorAttributes ErrorAttributes + */ + public ParticipantErrorController(ErrorAttributes errorAttributes) { + this.errorAttributes = errorAttributes; + } + + protected HttpStatus getStatus(HttpServletRequest request) { + Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); + if (statusCode == null) { + return HttpStatus.INTERNAL_SERVER_ERROR; + } + try { + return HttpStatus.valueOf(statusCode); + } catch (Exception ex) { + return HttpStatus.INTERNAL_SERVER_ERROR; + } + } + + /** + * Handle Errors not handled to GlobalControllerExceptionHandler. + * + * @param request HttpServletRequest + * @return ResponseEntity + */ + @RequestMapping(value = "${server.error.path}", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity> handleError(HttpServletRequest request) { + Map map = this.errorAttributes.getErrorAttributes(new ServletWebRequest(request), + ErrorAttributeOptions.defaults()); + + var sb = new StringBuilder(); + final Object error = map.get("error"); + if (error != null) { + sb.append(error.toString() + " "); + } + final Object message = map.get("message"); + if (message != null) { + sb.append(message.toString()); + } + + TypedSimpleResponse resp = new TypedSimpleResponse<>(); + resp.setErrorDetails(sb.toString()); + + return ResponseEntity.status(getStatus(request)).body(resp); + + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/ParticipantSimulatorAafFilter.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/ParticipantSimulatorAafFilter.java new file mode 100644 index 000000000..3008d2d17 --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/ParticipantSimulatorAafFilter.java @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.simulator.main.rest; + +import org.onap.policy.common.endpoints.http.server.aaf.AafGranularAuthFilter; +import org.onap.policy.common.utils.resources.MessageConstants; + +/** + * Class to manage AAF filters for the participant simulator component. + */ +public class ParticipantSimulatorAafFilter extends AafGranularAuthFilter { + + public static final String AAF_NODETYPE = MessageConstants.POLICY_CLAMP + "-participant-simulator"; + public static final String AAF_ROOT_PERMISSION = DEFAULT_NAMESPACE + "." + AAF_NODETYPE; + + @Override + public String getPermissionTypeRoot() { + return AAF_ROOT_PERMISSION; + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/simulation/SimulationProvider.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/simulation/SimulationProvider.java new file mode 100644 index 000000000..73ae80e29 --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/simulation/SimulationProvider.java @@ -0,0 +1,113 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.simulator.simulation; + +import java.util.List; +import java.util.Map; +import java.util.UUID; +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.common.acm.exception.AutomationCompositionException; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions; +import org.onap.policy.clamp.models.acm.concepts.Participant; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.onap.policy.clamp.models.acm.messages.rest.TypedSimpleResponse; +import org.springframework.stereotype.Service; + +/** + * This provider class simulation of participants and automation composition elements. + */ +@Service +public class SimulationProvider { + + private final ParticipantIntermediaryApi intermediaryApi; + + /** + * Create a participant simulation provider. + * + * @param intermediaryApi the intermediary to use for talking to the CLAMP runtime + */ + public SimulationProvider(ParticipantIntermediaryApi intermediaryApi) { + this.intermediaryApi = intermediaryApi; + } + + /** + * Get the automation compositions. + * + * @param name the automationComposition, null to get all + * @param version the automationComposition, null to get all + * @return the automation compositions + * @throws AutomationCompositionException on errors getting the automation compositions + */ + public AutomationCompositions getAutomationCompositions(String name, String version) + throws AutomationCompositionException { + return intermediaryApi.getAutomationCompositions(name, version); + } + + /** + * Get the simulated automation composition elements. + * + * @param name the automationCompositionElement, null to get all + * @param version the automationCompositionElement, null to get all + * @return the automation composition elements + */ + public Map getAutomationCompositionElements(String name, String version) { + return intermediaryApi.getAutomationCompositionElements(name, version); + } + + /** + * Update the given automation composition element in the simulator. + * + * @param element the automation composition element to update + * @return response simple response returned + */ + public TypedSimpleResponse updateAutomationCompositionElement( + AutomationCompositionElement element) { + TypedSimpleResponse response = new TypedSimpleResponse<>(); + response.setResponse(intermediaryApi.updateAutomationCompositionElementState(null, element.getId(), + element.getOrderedState(), element.getState(), ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE)); + return response; + } + + /** + * Get the current simulated participants. + * + * @param name the participant, null to get all + * @param version the participant, null to get all + * @return the list of participants + */ + public List getParticipants(String name, String version) { + return intermediaryApi.getParticipants(name, version); + } + + /** + * Update a simulated participant. + * + * @param participant the participant to update + * @return TypedSimpleResponse simple response + */ + public TypedSimpleResponse updateParticipant(Participant participant) { + TypedSimpleResponse response = new TypedSimpleResponse<>(); + response.setResponse( + intermediaryApi.updateParticipantState(participant.getDefinition(), participant.getParticipantState())); + return response; + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/simulation/rest/SimulationElementController.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/simulation/rest/SimulationElementController.java new file mode 100644 index 000000000..277638220 --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/simulation/rest/SimulationElementController.java @@ -0,0 +1,188 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.simulator.simulation.rest; + +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Authorization; +import io.swagger.annotations.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.ResponseHeader; +import java.util.Map; +import java.util.UUID; +import org.onap.policy.clamp.acm.participant.simulator.main.rest.AbstractRestController; +import org.onap.policy.clamp.acm.participant.simulator.simulation.SimulationProvider; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions; +import org.onap.policy.clamp.models.acm.messages.rest.TypedSimpleResponse; +import org.springframework.http.ResponseEntity; +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.RequestHeader; +import org.springframework.web.bind.annotation.RestController; + +/** + * Class to provide REST end points for participant simulator to query/update details of automationCompositionElements. + */ +@RestController +public class SimulationElementController extends AbstractRestController { + + /** + * Constructor. + * + * @param simulationProvider the Simulation Provider + */ + public SimulationElementController(SimulationProvider simulationProvider) { + super(simulationProvider); + } + + /** + * Queries details of all automation composition element within the simulator. + * + * @param requestId request ID used in ONAP logging + * @param name the name of the Automation Composition element to get, null to get all + * @param version the version of the Automation Composition element to get, null to get all + * @return the automation composition elements + */ + // @formatter:off + @GetMapping("/elements/{name}/{version}") + @ApiOperation( + value = "Query details of the requested simulated automation composition elements", + notes = "Queries details of the requested simulated automation composition elements, " + + "returning all automation composition element details", + response = AutomationCompositions.class, + tags = { + "Clamp Automation Composition Participant Simulator API" + }, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity> elements( + @RequestHeader(name = REQUEST_ID_NAME, required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Automation composition element name", required = true) @PathVariable("name") String name, + @ApiParam( + value = "Automation composition element version", + required = true) @PathVariable("version") String version) { + + return ResponseEntity + .ok() + .headers(super.getCommonHeaders(requestId)) + .body(getSimulationProvider().getAutomationCompositionElements(name, version)); + } + + /** + * Updates a automation composition element in the simulator. + * + * @param requestId request ID used in ONAP logging + * @param body the body of a automation composition element + * @return a response + */ + // @formatter:off + @PutMapping("/elements") + @ApiOperation( + value = "Updates simulated automation composition elements", + notes = "Updates simulated automation composition elements, " + + "returning the updated automation composition definition IDs", + response = TypedSimpleResponse.class, + tags = { + "Clamp Automation Composition Participant Simulator API" + }, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, + description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = VERSION_PATCH_NAME, + description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = VERSION_LATEST_NAME, + description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = REQUEST_ID_NAME, + description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class) + }, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity> update( + @RequestHeader(name = REQUEST_ID_NAME, required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam( + value = "Body of a automation composition element", + required = true) @RequestBody AutomationCompositionElement body) { + + return ResponseEntity + .ok() + .headers(super.getCommonHeaders(requestId)) + .body(getSimulationProvider().updateAutomationCompositionElement(body)); + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/simulation/rest/SimulationParticipantController.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/simulation/rest/SimulationParticipantController.java new file mode 100644 index 000000000..02e56aa6e --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/simulator/simulation/rest/SimulationParticipantController.java @@ -0,0 +1,181 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.simulator.simulation.rest; + +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Authorization; +import io.swagger.annotations.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.ResponseHeader; +import java.util.List; +import java.util.UUID; +import org.onap.policy.clamp.acm.participant.simulator.main.rest.AbstractRestController; +import org.onap.policy.clamp.acm.participant.simulator.simulation.SimulationProvider; +import org.onap.policy.clamp.models.acm.concepts.Participant; +import org.onap.policy.clamp.models.acm.messages.rest.TypedSimpleResponse; +import org.springframework.http.ResponseEntity; +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.RequestHeader; +import org.springframework.web.bind.annotation.RestController; + +/** + * Class to provide REST end points for participant simulator to query/update details of all participants. + */ +@RestController +public class SimulationParticipantController extends AbstractRestController { + + /** + * Constructor. + * + * @param simulationProvider the Simulation Provider + */ + public SimulationParticipantController(SimulationProvider simulationProvider) { + super(simulationProvider); + } + + /** + * Queries details of all participants within the simulator. + * + * @param requestId request ID used in ONAP logging + * @param name the name of the participant to get, null to get all + * @param version the version of the participant to get, null to get all + * @return the participants + */ + // @formatter:off + @GetMapping("/participants/{name}/{version}") + @ApiOperation(value = "Query details of the requested simulated participants", + notes = "Queries details of the requested simulated participants, " + + "returning all participant details", + response = List.class, + tags = { + "Clamp Automation Composition Participant Simulator API" + }, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity> participants( + @RequestHeader(name = REQUEST_ID_NAME, required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Participant name", required = true) @PathVariable("name") String name, + @ApiParam(value = "Participant version", required = true) @PathVariable("version") String version) { + + return ResponseEntity + .ok() + .headers(super.getCommonHeaders(requestId)) + .body(getSimulationProvider().getParticipants(name, version)); + } + + /** + * Updates a participant in the simulator. + * + * @param requestId request ID used in ONAP logging + * @param body the body of a participant + * @return a response + */ + // @formatter:off + @PutMapping("/participants") + @ApiOperation( + value = "Updates simulated participants", + notes = "Updates simulated participants, returning the updated automation composition definition IDs", + response = TypedSimpleResponse.class, + tags = { + "Clamp Automation Composition Participant Simulator API" + }, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, + description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = VERSION_PATCH_NAME, + description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = VERSION_LATEST_NAME, + description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader( + name = REQUEST_ID_NAME, + description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class) + }, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity> update( + @RequestHeader(name = REQUEST_ID_NAME, required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Body of a participant", required = true) @RequestBody Participant body) { + + return ResponseEntity + .ok() + .headers(super.getCommonHeaders(requestId)) + .body(getSimulationProvider().updateParticipant(body)); + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/ParticipantSimulatorApplication.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/ParticipantSimulatorApplication.java deleted file mode 100644 index 5e72d9479..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/ParticipantSimulatorApplication.java +++ /dev/null @@ -1,46 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.simulator; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.context.properties.ConfigurationPropertiesScan; -import org.springframework.context.annotation.ComponentScan; - -/** - * Starter. - * - */ -// @formatter:off -@SpringBootApplication -@ConfigurationPropertiesScan("org.onap.policy.clamp.controlloop.participant.simulator.main.parameters") -@ComponentScan({ - "org.onap.policy.clamp.controlloop.participant.simulator", - "org.onap.policy.clamp.controlloop.participant.intermediary", - "org.onap.policy.clamp.controlloop.common.rest" -}) -//@formatter:on -public class ParticipantSimulatorApplication { - - public static void main(String[] args) { - SpringApplication.run(ParticipantSimulatorApplication.class, args); - } -} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/AafConfiguration.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/AafConfiguration.java deleted file mode 100644 index c8922a1f5..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/AafConfiguration.java +++ /dev/null @@ -1,46 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP CLAMP - * ================================================================================ - * Copyright (C) 2017-2018 AT&T Intellectual Property. 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.onap.policy.clamp.controlloop.participant.simulator.config; - -import javax.servlet.Filter; -import org.onap.policy.clamp.controlloop.participant.simulator.main.rest.ParticipantSimulatorAafFilter; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; - -@Configuration -@Profile("clamp-aaf-authentication") -public class AafConfiguration { - - /** - * Method to return Aaf filter. - * - * @return Filter - */ - @Bean - public Filter aafFilter() { - return new ParticipantSimulatorAafFilter(); - } - -} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/ParticipantConfig.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/ParticipantConfig.java deleted file mode 100644 index f2079edf5..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/ParticipantConfig.java +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.simulator.config; - -import org.onap.policy.clamp.controlloop.common.rest.RequestResponseLoggingFilter; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.clamp.controlloop.participant.simulator.main.handler.ControlLoopElementHandler; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class ParticipantConfig { - - /** - * logging Filter configuration. - * - * @return FilterRegistrationBean - */ - @Bean - public FilterRegistrationBean loggingFilter() { - FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); - - registrationBean.setFilter(new RequestResponseLoggingFilter()); - registrationBean.addUrlPatterns("/onap/participantsim/v2/*"); - - return registrationBean; - } - - /** - * Register ControlLoopElementListener. - * - * @param intermediaryApi the ParticipantIntermediaryApi - * @param clElementHandler the ControlLoop Element Handler - */ - @Autowired - public void registerControlLoopElementListener(ParticipantIntermediaryApi intermediaryApi, - ControlLoopElementHandler clElementHandler) { - intermediaryApi.registerControlLoopElementListener(clElementHandler); - clElementHandler.setIntermediaryApi(intermediaryApi); - } -} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/SecurityConfig.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/SecurityConfig.java deleted file mode 100644 index cdfd5eac3..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/SecurityConfig.java +++ /dev/null @@ -1,39 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.simulator.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@Configuration -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - // @formatter:off - http.authorizeRequests() - .antMatchers().authenticated() - .anyRequest().authenticated() - .and().httpBasic().and().csrf().disable(); - // @formatter:on - } -} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/SpringFoxConfig.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/SpringFoxConfig.java deleted file mode 100644 index bf776140b..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/SpringFoxConfig.java +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.simulator.config; - -import org.onap.policy.clamp.controlloop.participant.simulator.simulation.rest.SimulationElementController; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; - -@Configuration -public class SpringFoxConfig { - - /** - * Docket Spring Fox Config. - * - * @return Docket - */ - @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2).select() - .apis(RequestHandlerSelectors.basePackage(SimulationElementController.class.getPackageName())) - .paths(PathSelectors.any()).build(); - } -} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/YamlConfiguration.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/YamlConfiguration.java deleted file mode 100644 index 28dd2f9bc..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/config/YamlConfiguration.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.simulator.config; - -import java.util.List; -import org.onap.policy.clamp.controlloop.common.rest.CoderHttpMesageConverter; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.MediaType; -import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.http.converter.StringHttpMessageConverter; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -@Configuration -public class YamlConfiguration implements WebMvcConfigurer { - - @Override - public void extendMessageConverters(List> converters) { - converters.add(new CoderHttpMesageConverter<>("yaml")); - converters.add(new CoderHttpMesageConverter<>("json")); - - StringHttpMessageConverter converter = new StringHttpMessageConverter(); - converter.setSupportedMediaTypes(List.of(MediaType.TEXT_PLAIN)); - converters.add(converter); - } -} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/handler/ControlLoopElementHandler.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/handler/ControlLoopElementHandler.java deleted file mode 100644 index fd46faf97..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/handler/ControlLoopElementHandler.java +++ /dev/null @@ -1,111 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.simulator.main.handler; - -import java.time.Instant; -import java.util.UUID; -import lombok.Setter; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -/** - * This class handles implementation of controlLoopElement updates. - */ -@Component -public class ControlLoopElementHandler implements ControlLoopElementListener { - - private static final Logger LOGGER = LoggerFactory.getLogger(ControlLoopElementHandler.class); - - @Setter - private ParticipantIntermediaryApi intermediaryApi; - - /** - * Callback method to handle a control loop element state change. - * - * @param controlLoopElementId the ID of the control loop element - * @param currentState the current state of the control loop element - * @param newState the state to which the control loop element is changing to - * @throws PfModelException in case of an exception - */ - @Override - public void controlLoopElementStateChange(ToscaConceptIdentifier controlLoopId, - UUID controlLoopElementId, ControlLoopState currentState, - ControlLoopOrderedState newState) throws PfModelException { - switch (newState) { - case UNINITIALISED: - intermediaryApi.updateControlLoopElementState(controlLoopId, - controlLoopElementId, newState, ControlLoopState.UNINITIALISED, - ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); - break; - case PASSIVE: - intermediaryApi.updateControlLoopElementState(controlLoopId, - controlLoopElementId, newState, ControlLoopState.PASSIVE, - ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); - break; - case RUNNING: - intermediaryApi.updateControlLoopElementState(controlLoopId, - controlLoopElementId, newState, ControlLoopState.RUNNING, - ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); - break; - default: - LOGGER.debug("Unknown orderedstate {}", newState); - break; - } - } - - /** - * Callback method to handle an update on a control loop element. - * - * @param element the information on the control loop element - * @param clElementDefinition toscaNodeTemplate - * @throws PfModelException in case of an exception - */ - @Override - public void controlLoopElementUpdate(ToscaConceptIdentifier controlLoopId, ControlLoopElement element, - ToscaNodeTemplate clElementDefinition) - throws PfModelException { - intermediaryApi.updateControlLoopElementState(controlLoopId, element.getId(), element.getOrderedState(), - ControlLoopState.PASSIVE, ParticipantMessageType.CONTROL_LOOP_UPDATE); - } - - @Override - public void handleStatistics(UUID controlLoopElementId) throws PfModelException { - var clElement = intermediaryApi.getControlLoopElement(controlLoopElementId); - if (clElement != null) { - var clElementStatistics = new ClElementStatistics(); - clElementStatistics.setControlLoopState(clElement.getState()); - clElementStatistics.setTimeStamp(Instant.now()); - intermediaryApi.updateControlLoopElementStatistics(controlLoopElementId, clElementStatistics); - } - } - -} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/ParticipantSimulatorParameters.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/ParticipantSimulatorParameters.java deleted file mode 100644 index 99579006c..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/ParticipantSimulatorParameters.java +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.simulator.main.parameters; - -import javax.validation.Valid; -import javax.validation.constraints.NotNull; -import lombok.Getter; -import lombok.Setter; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.validation.annotation.Validated; - -/** - * Class to hold all parameters needed for the participant simulator. - * - */ -@Validated -@Getter -@Setter -@ConfigurationProperties(prefix = "participant") -public class ParticipantSimulatorParameters implements ParticipantParameters { - - @Valid - @NotNull - private ParticipantIntermediaryParameters intermediaryParameters; -} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/AbstractRestController.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/AbstractRestController.java deleted file mode 100644 index 5a6dbfa81..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/AbstractRestController.java +++ /dev/null @@ -1,102 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.simulator.main.rest; - -import io.swagger.annotations.Api; -import io.swagger.annotations.BasicAuthDefinition; -import io.swagger.annotations.Info; -import io.swagger.annotations.SecurityDefinition; -import io.swagger.annotations.SwaggerDefinition; -import io.swagger.annotations.Tag; -import java.net.HttpURLConnection; -import javax.ws.rs.core.MediaType; -import lombok.AccessLevel; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.participant.simulator.simulation.SimulationProvider; -import org.springframework.web.bind.annotation.RequestMapping; - -/** - * Common superclass to provide REST endpoints for the participant simulator. - */ -// @formatter:off -@RequestMapping(value = "/v2", produces = {MediaType.APPLICATION_JSON, AbstractRestController.APPLICATION_YAML}) -@Api(value = "Participant Simulator API") -@SwaggerDefinition( - info = @Info(description = - "Participant Simulator", version = "v1.0", - title = "Participant Simulator"), - consumes = {MediaType.APPLICATION_JSON, AbstractRestController.APPLICATION_YAML}, - produces = {MediaType.APPLICATION_JSON, AbstractRestController.APPLICATION_YAML}, - schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS}, - tags = {@Tag(name = "participantsim", description = "Participant Simulator")}, - securityDefinition = @SecurityDefinition(basicAuthDefinitions = {@BasicAuthDefinition(key = "basicAuth")})) -// @formatter:on -public abstract class AbstractRestController { - public static final String APPLICATION_YAML = "application/yaml"; - - public static final String EXTENSION_NAME = "interface info"; - - public static final String API_VERSION_NAME = "api-version"; - public static final String API_VERSION = "1.0.0"; - - public static final String LAST_MOD_NAME = "last-mod-release"; - public static final String LAST_MOD_RELEASE = "Dublin"; - - public static final String VERSION_MINOR_NAME = "X-MinorVersion"; - public static final String VERSION_MINOR_DESCRIPTION = - "Used to request or communicate a MINOR version back from the client" - + " to the server, and from the server back to the client"; - - public static final String VERSION_PATCH_NAME = "X-PatchVersion"; - public static final String VERSION_PATCH_DESCRIPTION = "Used only to communicate a PATCH version in a response for" - + " troubleshooting purposes only, and will not be provided by" + " the client on request"; - - public static final String VERSION_LATEST_NAME = "X-LatestVersion"; - public static final String VERSION_LATEST_DESCRIPTION = "Used only to communicate an API's latest version"; - - public static final String REQUEST_ID_NAME = "X-ONAP-RequestID"; - public static final String REQUEST_ID_HDR_DESCRIPTION = "Used to track REST transactions for logging purpose"; - public static final String REQUEST_ID_PARAM_DESCRIPTION = "RequestID for http transaction"; - - public static final String AUTHORIZATION_TYPE = "basicAuth"; - - public static final int AUTHENTICATION_ERROR_CODE = HttpURLConnection.HTTP_UNAUTHORIZED; - public static final int AUTHORIZATION_ERROR_CODE = HttpURLConnection.HTTP_FORBIDDEN; - public static final int SERVER_ERROR_CODE = HttpURLConnection.HTTP_INTERNAL_ERROR; - - public static final String AUTHENTICATION_ERROR_MESSAGE = "Authentication Error"; - public static final String AUTHORIZATION_ERROR_MESSAGE = "Authorization Error"; - public static final String SERVER_ERROR_MESSAGE = "Internal Server Error"; - - @Getter(AccessLevel.PROTECTED) - // The provider for simulation requests - private SimulationProvider simulationProvider; - - /** - * create a Rest Controller. - * - * @param simulationProvider the provider for the simulation participant - */ - protected AbstractRestController(SimulationProvider simulationProvider) { - this.simulationProvider = simulationProvider; - } - -} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/GlobalControllerExceptionHandler.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/GlobalControllerExceptionHandler.java deleted file mode 100644 index 8648c253e..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/GlobalControllerExceptionHandler.java +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * ================================================================================ - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.simulator.main.rest; - -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; -import org.onap.policy.clamp.controlloop.models.messages.rest.SimpleResponse; -import org.onap.policy.clamp.controlloop.models.rest.RestUtils; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.RestControllerAdvice; - -@RestControllerAdvice -public class GlobalControllerExceptionHandler { - - /** - * Handle ControlLoopException. - * - * @param ex ControlLoopException - * @return ResponseEntity - */ - @ExceptionHandler(ControlLoopException.class) - public ResponseEntity handleBadRequest(ControlLoopException ex) { - return RestUtils.toSimpleResponse(ex); - } -} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/ParticipantErrorController.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/ParticipantErrorController.java deleted file mode 100644 index 75546196a..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/ParticipantErrorController.java +++ /dev/null @@ -1,97 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * ================================================================================ - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.simulator.main.rest; - -import java.util.Map; -import javax.servlet.RequestDispatcher; -import javax.servlet.http.HttpServletRequest; -import org.onap.policy.clamp.controlloop.models.messages.rest.SimpleResponse; -import org.onap.policy.clamp.controlloop.models.messages.rest.TypedSimpleResponse; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.boot.web.servlet.error.ErrorController; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.context.request.ServletWebRequest; - -@Controller -public class ParticipantErrorController implements ErrorController { - - private final ErrorAttributes errorAttributes; - - @Value("${server.error.path}") - private String path; - - /** - * Constructor. - * - * @param errorAttributes ErrorAttributes - */ - public ParticipantErrorController(ErrorAttributes errorAttributes) { - this.errorAttributes = errorAttributes; - } - - protected HttpStatus getStatus(HttpServletRequest request) { - Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); - if (statusCode == null) { - return HttpStatus.INTERNAL_SERVER_ERROR; - } - try { - return HttpStatus.valueOf(statusCode); - } catch (Exception ex) { - return HttpStatus.INTERNAL_SERVER_ERROR; - } - } - - /** - * Handle Errors not handled to GlobalControllerExceptionHandler. - * - * @param request HttpServletRequest - * @return ResponseEntity - */ - @RequestMapping(value = "${server.error.path}", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity> handleError(HttpServletRequest request) { - Map map = this.errorAttributes.getErrorAttributes(new ServletWebRequest(request), - ErrorAttributeOptions.defaults()); - - var sb = new StringBuilder(); - final Object error = map.get("error"); - if (error != null) { - sb.append(error.toString() + " "); - } - final Object message = map.get("message"); - if (message != null) { - sb.append(message.toString()); - } - - TypedSimpleResponse resp = new TypedSimpleResponse<>(); - resp.setErrorDetails(sb.toString()); - - return ResponseEntity.status(getStatus(request)).body(resp); - - } -} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/ParticipantSimulatorAafFilter.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/ParticipantSimulatorAafFilter.java deleted file mode 100644 index f200f975a..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/ParticipantSimulatorAafFilter.java +++ /dev/null @@ -1,38 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.simulator.main.rest; - -import org.onap.policy.common.endpoints.http.server.aaf.AafGranularAuthFilter; -import org.onap.policy.common.utils.resources.MessageConstants; - -/** - * Class to manage AAF filters for the participant simulator component. - */ -public class ParticipantSimulatorAafFilter extends AafGranularAuthFilter { - - public static final String AAF_NODETYPE = MessageConstants.POLICY_CLAMP + "-participant-simulator"; - public static final String AAF_ROOT_PERMISSION = DEFAULT_NAMESPACE + "." + AAF_NODETYPE; - - @Override - public String getPermissionTypeRoot() { - return AAF_ROOT_PERMISSION; - } -} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/SimulationProvider.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/SimulationProvider.java deleted file mode 100644 index 688f7df6b..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/SimulationProvider.java +++ /dev/null @@ -1,110 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.simulator.simulation; - -import java.util.List; -import java.util.Map; -import java.util.UUID; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; -import org.onap.policy.clamp.controlloop.models.messages.rest.TypedSimpleResponse; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; -import org.springframework.stereotype.Service; - -/** - * This provider class simulation of participants and control loop elements. - */ -@Service -public class SimulationProvider { - - private final ParticipantIntermediaryApi intermediaryApi; - - /** - * Create a participant simulation provider. - * @param intermediaryApi the intermediary to use for talking to the CLAMP runtime - */ - public SimulationProvider(ParticipantIntermediaryApi intermediaryApi) { - this.intermediaryApi = intermediaryApi; - } - - /** - * Get the control loops. - * - * @param name the controlLoop, null to get all - * @param version the controlLoop, null to get all - * @return the control loops - * @throws ControlLoopException on errors getting the control loops - */ - public ControlLoops getControlLoops(String name, String version) throws ControlLoopException { - return intermediaryApi.getControlLoops(name, version); - } - - /** - * Get the simulated control loop elements. - * - * @param name the controlLoopElement, null to get all - * @param version the controlLoopElement, null to get all - * @return the control loop elements - */ - public Map getControlLoopElements(String name, String version) { - return intermediaryApi.getControlLoopElements(name, version); - } - - /** - * Update the given control loop element in the simulator. - * - * @param element the control loop element to update - * @return response simple response returned - */ - public TypedSimpleResponse updateControlLoopElement(ControlLoopElement element) { - TypedSimpleResponse response = new TypedSimpleResponse<>(); - response.setResponse(intermediaryApi.updateControlLoopElementState(null, element.getId(), - element.getOrderedState(), element.getState(), ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE)); - return response; - } - - /** - * Get the current simulated participants. - * - * @param name the participant, null to get all - * @param version the participant, null to get all - * @return the list of participants - */ - public List getParticipants(String name, String version) { - return intermediaryApi.getParticipants(name, version); - } - - /** - * Update a simulated participant. - * - * @param participant the participant to update - * @return TypedSimpleResponse simple response - */ - public TypedSimpleResponse updateParticipant(Participant participant) { - TypedSimpleResponse response = new TypedSimpleResponse<>(); - response.setResponse( - intermediaryApi.updateParticipantState(participant.getDefinition(), participant.getParticipantState())); - return response; - } -} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationElementController.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationElementController.java deleted file mode 100644 index e0569cf0f..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationElementController.java +++ /dev/null @@ -1,183 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.simulator.simulation.rest; - -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Authorization; -import io.swagger.annotations.Extension; -import io.swagger.annotations.ExtensionProperty; -import io.swagger.annotations.ResponseHeader; -import java.util.Map; -import java.util.UUID; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; -import org.onap.policy.clamp.controlloop.models.messages.rest.TypedSimpleResponse; -import org.onap.policy.clamp.controlloop.participant.simulator.main.rest.AbstractRestController; -import org.onap.policy.clamp.controlloop.participant.simulator.simulation.SimulationProvider; -import org.springframework.http.ResponseEntity; -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.RequestHeader; -import org.springframework.web.bind.annotation.RestController; - -/** - * Class to provide REST end points for participant simulator to query/update details of controlLoopElements. - */ -@RestController -public class SimulationElementController extends AbstractRestController { - - /** - * Constructor. - * - * @param simulationProvider the Simulation Provider - */ - public SimulationElementController(SimulationProvider simulationProvider) { - super(simulationProvider); - } - - /** - * Queries details of all control loop element within the simulator. - * - * @param requestId request ID used in ONAP logging - * @param name the name of the Control Loop element to get, null to get all - * @param version the version of the Control Loop element to get, null to get all - * @return the control loop elements - */ - // @formatter:off - @GetMapping("/elements/{name}/{version}") - @ApiOperation( - value = "Query details of the requested simulated control loop elements", - notes = "Queries details of the requested simulated control loop elements, " - + "returning all control loop element details", - response = ControlLoops.class, - tags = { - "Clamp Control Loop Participant Simulator API" - }, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class)}, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - } - ) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - public ResponseEntity> elements( - @RequestHeader( - name = REQUEST_ID_NAME, - required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Control loop element name", required = true) @PathVariable("name") String name, - @ApiParam( - value = "Control loop element version", - required = true) @PathVariable("version") String version) { - - return ResponseEntity.ok().body(getSimulationProvider().getControlLoopElements(name, version)); - } - - /** - * Updates a control loop element in the simulator. - * - * @param requestId request ID used in ONAP logging - * @param body the body of a control loop element - * @return a response - */ - // @formatter:off - @PutMapping("/elements") - @ApiOperation( - value = "Updates simulated control loop elements", - notes = "Updates simulated control loop elements, returning the updated control loop definition IDs", - response = TypedSimpleResponse.class, - tags = { - "Clamp Control Loop Participant Simulator API" - }, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, - description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = VERSION_PATCH_NAME, - description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = VERSION_LATEST_NAME, - description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = REQUEST_ID_NAME, - description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class) - }, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - } - ) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - public ResponseEntity> update( - @RequestHeader( - name = REQUEST_ID_NAME, - required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Body of a control loop element", required = true) @RequestBody ControlLoopElement body) { - - return ResponseEntity.ok().body(getSimulationProvider().updateControlLoopElement(body)); - } -} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationParticipantController.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationParticipantController.java deleted file mode 100644 index 25ae4ac22..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationParticipantController.java +++ /dev/null @@ -1,175 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.simulator.simulation.rest; - -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Authorization; -import io.swagger.annotations.Extension; -import io.swagger.annotations.ExtensionProperty; -import io.swagger.annotations.ResponseHeader; -import java.util.List; -import java.util.UUID; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant; -import org.onap.policy.clamp.controlloop.models.messages.rest.TypedSimpleResponse; -import org.onap.policy.clamp.controlloop.participant.simulator.main.rest.AbstractRestController; -import org.onap.policy.clamp.controlloop.participant.simulator.simulation.SimulationProvider; -import org.springframework.http.ResponseEntity; -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.RequestHeader; -import org.springframework.web.bind.annotation.RestController; - -/** - * Class to provide REST end points for participant simulator to query/update details of all participants. - */ -@RestController -public class SimulationParticipantController extends AbstractRestController { - - /** - * Constructor. - * - * @param simulationProvider the Simulation Provider - */ - public SimulationParticipantController(SimulationProvider simulationProvider) { - super(simulationProvider); - } - - /** - * Queries details of all participants within the simulator. - * - * @param requestId request ID used in ONAP logging - * @param name the name of the participant to get, null to get all - * @param version the version of the participant to get, null to get all - * @return the participants - */ - // @formatter:off - @GetMapping("/participants/{name}/{version}") - @ApiOperation(value = "Query details of the requested simulated participants", - notes = "Queries details of the requested simulated participants, " - + "returning all participant details", - response = List.class, - tags = { - "Clamp Control Loop Participant Simulator API" - }, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class)}, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - } - ) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - public ResponseEntity> participants( - @RequestHeader(name = REQUEST_ID_NAME, required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Participant name", required = true) @PathVariable("name") String name, - @ApiParam(value = "Participant version", required = true) @PathVariable("version") String version) { - - return ResponseEntity.ok().body(getSimulationProvider().getParticipants(name, version)); - } - - /** - * Updates a participant in the simulator. - * - * @param requestId request ID used in ONAP logging - * @param body the body of a participant - * @return a response - */ - // @formatter:off - @PutMapping("/participants") - @ApiOperation( - value = "Updates simulated participants", - notes = "Updates simulated participants, returning the updated control loop definition IDs", - response = TypedSimpleResponse.class, - tags = { - "Clamp Control Loop Participant Simulator API" - }, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - responseHeaders = { - @ResponseHeader( - name = VERSION_MINOR_NAME, - description = VERSION_MINOR_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = VERSION_PATCH_NAME, - description = VERSION_PATCH_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = VERSION_LATEST_NAME, - description = VERSION_LATEST_DESCRIPTION, - response = String.class), - @ResponseHeader( - name = REQUEST_ID_NAME, - description = REQUEST_ID_HDR_DESCRIPTION, - response = UUID.class) - }, - extensions = { - @Extension - ( - name = EXTENSION_NAME, - properties = { - @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), - @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) - } - ) - } - ) - @ApiResponses( - value = { - @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), - @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), - @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) - } - ) - // @formatter:on - public ResponseEntity> update( - @RequestHeader(name = REQUEST_ID_NAME, required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Body of a participant", required = true) @RequestBody Participant body) { - - return ResponseEntity.ok().body(getSimulationProvider().updateParticipant(body)); - } -} diff --git a/participant/participant-impl/participant-impl-simulator/src/main/resources/config/application.yaml b/participant/participant-impl/participant-impl-simulator/src/main/resources/config/application.yaml index d750d46d2..e20f0ebf5 100644 --- a/participant/participant-impl/participant-impl-simulator/src/main/resources/config/application.yaml +++ b/participant/participant-impl/participant-impl-simulator/src/main/resources/config/application.yaml @@ -21,17 +21,17 @@ participant: participantType: name: org.onap.PM_CDS_Blueprint version: 1.0.0 - clampControlLoopTopics: + clampAutomationCompositionTopics: topicSources: - - topic: POLICY-CLRUNTIME-PARTICIPANT + topic: POLICY-ACRUNTIME-PARTICIPANT servers: - ${topicServer:localhost} topicCommInfrastructure: dmaap fetchTimeout: 15000 topicSinks: - - topic: POLICY-CLRUNTIME-PARTICIPANT + topic: POLICY-ACRUNTIME-PARTICIPANT servers: - ${topicServer:localhost} topicCommInfrastructure: dmaap diff --git a/participant/participant-impl/participant-impl-simulator/src/main/resources/version.txt b/participant/participant-impl/participant-impl-simulator/src/main/resources/version.txt index dbd67585f..5fcdcab5a 100644 --- a/participant/participant-impl/participant-impl-simulator/src/main/resources/version.txt +++ b/participant/participant-impl/participant-impl-simulator/src/main/resources/version.txt @@ -1,4 +1,4 @@ -ONAP Tosca defined control loop Participant +ONAP Tosca defined automation composition Participant Version: ${project.version} Built (UTC): ${maven.build.timestamp} ONAP https://wiki.onap.org diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/endtoend/ParticipantSimulatorTest.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/endtoend/ParticipantSimulatorTest.java new file mode 100644 index 000000000..de6855d03 --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/endtoend/ParticipantSimulatorTest.java @@ -0,0 +1,288 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.simulator.endtoend; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import java.util.Map; +import java.util.UUID; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import org.glassfish.jersey.client.ClientProperties; +import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.acm.participant.intermediary.comm.AutomationCompositionUpdateListener; +import org.onap.policy.clamp.acm.participant.intermediary.handler.ParticipantHandler; +import org.onap.policy.clamp.acm.participant.simulator.main.parameters.CommonTestData; +import org.onap.policy.clamp.acm.participant.simulator.main.rest.AbstractRestController; +import org.onap.policy.clamp.acm.participant.simulator.main.rest.TestListenerUtils; +import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.Participant; +import org.onap.policy.clamp.models.acm.concepts.ParticipantState; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionUpdate; +import org.onap.policy.clamp.models.acm.messages.rest.TypedSimpleResponse; +import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.gson.GsonMessageBodyHandler; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@TestPropertySource(locations = {"classpath:application_test.properties"}) +class ParticipantSimulatorTest { + + private static final String PARTICIPANTS_ENDPOINT = "participants"; + private static final String ELEMENTS_ENDPOINT = "elements"; + private static final CommInfrastructure INFRA = CommInfrastructure.NOOP; + private static final String TOPIC = "my-topic"; + + @Value("${spring.security.user.name}") + private String user; + + @Value("${spring.security.user.password}") + private String password; + + @LocalServerPort + private int randomServerPort; + + @Autowired + private ParticipantIntermediaryApi participantIntermediaryApi; + + @Autowired + private ParticipantHandler participantHandler; + + private static final Object lockit = new Object(); + private boolean check = false; + + private void setUp() throws Exception { + synchronized (lockit) { + if (!check) { + check = true; + AutomationCompositionUpdateListener acUpdateListener = + new AutomationCompositionUpdateListener(participantHandler); + + AutomationCompositionUpdate automationCompositionUpdateMsg = + TestListenerUtils.createAutomationCompositionUpdateMsg(); + acUpdateListener.onTopicEvent(INFRA, TOPIC, null, automationCompositionUpdateMsg); + + } + } + } + + private String getPath(String path) { + return "http://localhost:" + randomServerPort + "/onap/participantsim/v2/" + path; + } + + void testSwagger(String endPoint) { + final Client client = ClientBuilder.newBuilder().build(); + + client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true"); + client.register(GsonMessageBodyHandler.class); + client.register(HttpAuthenticationFeature.basic(user, password)); + + final WebTarget webTarget = client.target(getPath("api-docs")); + + Response response = webTarget.request(MediaType.APPLICATION_JSON).get(); + + assertThat(response.getStatus()).isEqualTo(200); + assertTrue(response.readEntity(String.class).contains("/onap/participantsim/v2/" + endPoint)); + } + + @Test + void testEndParticipatsSwagger() { + testSwagger(PARTICIPANTS_ENDPOINT); + } + + @Test + void testElementsSwagger() { + testSwagger(ELEMENTS_ENDPOINT); + } + + @Test + void testProducerYaml() { + final Client client = ClientBuilder.newBuilder().build(); + + client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true"); + client.register(GsonMessageBodyHandler.class); + client.register(HttpAuthenticationFeature.basic(user, password)); + + String path = getPath(PARTICIPANTS_ENDPOINT + "/org.onap.PM_CDS_Blueprint/1"); + final WebTarget webTarget = client.target(path); + + Response response = webTarget.request("application/yaml").get(); + + assertThat(response.getStatus()).isEqualTo(200); + } + + @Test + void testQuery_Unauthorized() throws Exception { + String path = PARTICIPANTS_ENDPOINT + "/org.onap.PM_CDS_Blueprint/1"; + + Response response = performRequest(path, true, null).get(); + assertThat(response.getStatus()).isEqualTo(200); + + // unauthorized call + response = performRequest(path, false, null).get(); + assertThat(response.getStatus()).isEqualTo(401); + } + + private Invocation.Builder performRequest(String endpoint, boolean includeAuth, UUID uuid) { + final Client client = ClientBuilder.newBuilder().build(); + + client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true"); + client.register(GsonMessageBodyHandler.class); + if (includeAuth) { + client.register(HttpAuthenticationFeature.basic(user, password)); + } + Invocation.Builder builder = client.target(getPath(endpoint)).request(MediaType.APPLICATION_JSON); + if (uuid != null) { + builder = builder.header(AbstractRestController.REQUEST_ID_NAME, uuid.toString()); + } + return builder; + } + + private Response performGet(String endpoint, UUID uuid) throws Exception { + return performRequest(endpoint, true, uuid).get(); + } + + @Test + void testQueryParticipants() throws Exception { + Participant participant = new Participant(); + ToscaConceptIdentifier participantId = CommonTestData.getParticipantId(); + participant.setDefinition(participantId); + participant.setName(participantId.getName()); + participant.setVersion(participantId.getVersion()); + UUID uuid = UUID.randomUUID(); + + // GET REST call for querying the participants + Response response = performGet( + PARTICIPANTS_ENDPOINT + "/" + participant.getKey().getName() + "/" + participant.getKey().getVersion(), + uuid); + checkResponseEntity(response, 200, uuid); + + Participant[] returnValue = response.readEntity(Participant[].class); + assertThat(returnValue).hasSize(1); + // Verify the result of GET participants with what is stored + assertEquals(participant.getDefinition(), returnValue[0].getDefinition()); + } + + private void checkResponseEntity(Response response, int status, UUID uuid) { + assertThat(response.getStatus()).isEqualTo(status); + assertThat(getHeader(response.getHeaders(), AbstractRestController.VERSION_MINOR_NAME)).isEqualTo("0"); + assertThat(getHeader(response.getHeaders(), AbstractRestController.VERSION_PATCH_NAME)).isEqualTo("0"); + assertThat(getHeader(response.getHeaders(), AbstractRestController.VERSION_LATEST_NAME)).isEqualTo("1.0.0"); + assertThat(getHeader(response.getHeaders(), AbstractRestController.REQUEST_ID_NAME)).isEqualTo(uuid.toString()); + } + + private String getHeader(MultivaluedMap httpHeaders, String param) { + List list = httpHeaders.get(param); + assertThat(list).hasSize(1); + assertThat(list.get(0)).isNotNull(); + return (String) list.get(0); + } + + @Test + void testQueryAutomationCompositionElements() throws Exception { + setUp(); + UUID uuid = UUID.randomUUID(); + ToscaConceptIdentifier participantId = CommonTestData.getParticipantId(); + + // GET REST call for querying the automationComposition elements + Response response = + performGet(ELEMENTS_ENDPOINT + "/" + participantId.getName() + "/" + participantId.getVersion(), uuid); + checkResponseEntity(response, 200, uuid); + + Map returnValue = response.readEntity(Map.class); + // Verify the result of GET automation composition elements with what is stored + assertThat(returnValue).isEmpty(); + } + + private Response performPut(String endpoint, final Entity entity, UUID uuid) throws Exception { + return performRequest(endpoint, true, uuid).put(entity); + } + + @Test + void testUpdateParticipant() throws Exception { + setUp(); + List participants = participantIntermediaryApi.getParticipants( + CommonTestData.getParticipantId().getName(), CommonTestData.getParticipantId().getVersion()); + assertEquals(ParticipantState.UNKNOWN, participants.get(0).getParticipantState()); + // Change the state of the participant to PASSIVE from UNKNOWN + participants.get(0).setParticipantState(ParticipantState.PASSIVE); + UUID uuid = UUID.randomUUID(); + + // PUT REST call for updating Participant + Response response = performPut(PARTICIPANTS_ENDPOINT, Entity.json(participants.get(0)), uuid); + checkResponseEntity(response, 200, uuid); + + TypedSimpleResponse resp = + response.readEntity(new GenericType>() {}); + assertNotNull(resp.getResponse()); + // Verify the response and state returned by PUT REST call for updating participants + assertEquals(participants.get(0).getDefinition(), resp.getResponse().getDefinition()); + assertEquals(ParticipantState.PASSIVE, resp.getResponse().getParticipantState()); + } + + @Test + void testUpdateAutomationCompositionElement() throws Exception { + setUp(); + AutomationComposition automationComposition = TestListenerUtils.createAutomationComposition(); + Map automationCompositionElements = + participantIntermediaryApi.getAutomationCompositionElements(automationComposition.getDefinition().getName(), + automationComposition.getDefinition().getVersion()); + + UUID uuid = automationCompositionElements.keySet().iterator().next(); + AutomationCompositionElement automationCompositionElement = automationCompositionElements.get(uuid); + + automationCompositionElement.setOrderedState(AutomationCompositionOrderedState.PASSIVE); + // PUT REST call for updating AutomationCompositionElement + Response response = performPut(ELEMENTS_ENDPOINT, Entity.json(automationCompositionElement), uuid); + checkResponseEntity(response, 200, uuid); + + TypedSimpleResponse resp = + response.readEntity(new GenericType>() {}); + assertNotNull(resp.getResponse()); + // Verify the response and state returned by PUT REST call for updating participants + assertEquals(automationCompositionElement.getDefinition(), resp.getResponse().getDefinition()); + assertEquals(AutomationCompositionOrderedState.PASSIVE, resp.getResponse().getOrderedState()); + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/main/handler/AutomationCompositionElementHandlerTest.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/main/handler/AutomationCompositionElementHandlerTest.java new file mode 100644 index 000000000..360485efa --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/main/handler/AutomationCompositionElementHandlerTest.java @@ -0,0 +1,91 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.simulator.main.handler; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.Mockito.when; + +import java.util.UUID; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; + +class AutomationCompositionElementHandlerTest { + + private static final String ID_NAME = "org.onap.PM_CDS_Blueprint"; + private static final String ID_VERSION = "1.0.1"; + private static final UUID automationCompositionElementId = UUID.randomUUID(); + private static final ToscaConceptIdentifier automationCompositionId = + new ToscaConceptIdentifier(ID_NAME, ID_VERSION); + + @Test + void testSimulatorHandlerExceptions() throws PfModelException { + AutomationCompositionElementHandler handler = getTestingHandler(); + + assertDoesNotThrow(() -> handler.automationCompositionElementStateChange(automationCompositionId, + automationCompositionElementId, AutomationCompositionState.UNINITIALISED, + AutomationCompositionOrderedState.PASSIVE)); + + assertDoesNotThrow(() -> handler.automationCompositionElementStateChange(automationCompositionId, + automationCompositionElementId, AutomationCompositionState.RUNNING, + AutomationCompositionOrderedState.UNINITIALISED)); + + assertDoesNotThrow(() -> handler.automationCompositionElementStateChange(automationCompositionId, + automationCompositionElementId, AutomationCompositionState.PASSIVE, + AutomationCompositionOrderedState.RUNNING)); + var element = getTestingAcElement(); + var acElementDefinition = Mockito.mock(ToscaNodeTemplate.class); + + assertDoesNotThrow( + () -> handler.automationCompositionElementUpdate(automationCompositionId, element, acElementDefinition)); + + assertDoesNotThrow(() -> handler.handleStatistics(automationCompositionElementId)); + } + + AutomationCompositionElementHandler getTestingHandler() { + var handler = new AutomationCompositionElementHandler(); + var intermediaryApi = Mockito.mock(ParticipantIntermediaryApi.class); + var element = getTestingAcElement(); + when(intermediaryApi.getAutomationCompositionElement(automationCompositionElementId)).thenReturn(element); + handler.setIntermediaryApi(intermediaryApi); + return handler; + } + + AutomationCompositionElement getTestingAcElement() { + var element = new AutomationCompositionElement(); + element.setDefinition(automationCompositionId); + element.setDescription("Description"); + element.setId(automationCompositionElementId); + element.setOrderedState(AutomationCompositionOrderedState.UNINITIALISED); + element.setParticipantId(automationCompositionId); + element.setState(AutomationCompositionState.UNINITIALISED); + var template = Mockito.mock(ToscaServiceTemplate.class); + element.setToscaServiceTemplateFragment(template); + return element; + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/main/parameters/CommonTestData.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/main/parameters/CommonTestData.java new file mode 100644 index 000000000..6af454a42 --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/main/parameters/CommonTestData.java @@ -0,0 +1,140 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.simulator.main.parameters; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import org.onap.policy.common.endpoints.parameters.TopicParameters; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +/** + * Class to hold/create all parameters for test cases. + */ +public class CommonTestData { + public static final String PARTICIPANT_GROUP_NAME = "AutomationCompositionParticipantGroup"; + public static final String DESCRIPTION = "Participant description"; + public static final long TIME_INTERVAL = 2000; + public static final List TOPIC_PARAMS = Arrays.asList(getTopicParams()); + + public static final Coder CODER = new StandardCoder(); + + /** + * Get ParticipantSimulatorParameters. + * + * @return ParticipantSimulatorParameters + */ + public ParticipantSimulatorParameters getParticipantSimulatorParameters() { + try { + return CODER.convert(getParticipantParameterGroupMap(PARTICIPANT_GROUP_NAME), + ParticipantSimulatorParameters.class); + } catch (final CoderException e) { + throw new RuntimeException("cannot create ParticipantSimulatorParameters from map", e); + } + } + + /** + * Returns a property map for a ApexStarterParameterGroup map for test cases. + * + * @param name name of the parameters + * + * @return a property map suitable for constructing an object + */ + public Map getParticipantParameterGroupMap(final String name) { + final Map map = new TreeMap<>(); + + map.put("intermediaryParameters", getIntermediaryParametersMap(false)); + return map; + } + + /** + * Returns a property map for a intermediaryParameters map for test cases. + * + * @param isEmpty boolean value to represent that object created should be empty or not + * @return a property map suitable for constructing an object + */ + public Map getIntermediaryParametersMap(final boolean isEmpty) { + final Map map = new TreeMap<>(); + if (!isEmpty) { + map.put("name", "Participant parameters"); + map.put("reportingTimeIntervalMs", TIME_INTERVAL); + map.put("description", DESCRIPTION); + map.put("participantId", getParticipantId()); + map.put("participantType", getParticipantId()); + map.put("clampAutomationCompositionTopics", getTopicParametersMap(false)); + } + + return map; + } + + /** + * Returns a property map for a TopicParameters map for test cases. + * + * @param isEmpty boolean value to represent that object created should be empty or not + * @return a property map suitable for constructing an object + */ + public Map getTopicParametersMap(final boolean isEmpty) { + final Map map = new TreeMap<>(); + if (!isEmpty) { + map.put("topicSources", TOPIC_PARAMS); + map.put("topicSinks", TOPIC_PARAMS); + } + return map; + } + + /** + * Returns topic parameters for test cases. + * + * @return topic parameters + */ + public static TopicParameters getTopicParams() { + final TopicParameters topicParams = new TopicParameters(); + topicParams.setTopic("POLICY-ACRUNTIME-PARTICIPANT"); + topicParams.setTopicCommInfrastructure("dmaap"); + topicParams.setServers(Arrays.asList("localhost")); + return topicParams; + } + + /** + * Returns participantId for test cases. + * + * @return participant Id + */ + public static ToscaConceptIdentifier getParticipantId() { + final ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_CDS_Blueprint", "1.0.0"); + return participantId; + } + + /** + * Nulls out a field within a JSON string. + * + * @param json JSON string + * @param field field to be nulled out + * @return a new JSON string with the field nulled out + */ + public String nullifyField(String json, String field) { + return json.replace(field + "\"", field + "\":null, \"" + field + "Xxx\""); + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/main/parameters/TestParticipantSimulatorParameters.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/main/parameters/TestParticipantSimulatorParameters.java new file mode 100644 index 000000000..c763d09a3 --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/main/parameters/TestParticipantSimulatorParameters.java @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.simulator.main.parameters; + +import static org.assertj.core.api.Assertions.assertThat; + +import javax.validation.Validation; +import javax.validation.ValidatorFactory; +import org.junit.jupiter.api.Test; + +/** + * Class to perform unit test of {@link ParticipantParameterGroup}. + */ +class TestParticipantSimulatorParameters { + private CommonTestData commonTestData = new CommonTestData(); + private ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); + + @Test + void testParticipantParameterGroup() { + final ParticipantSimulatorParameters participantParameters = commonTestData.getParticipantSimulatorParameters(); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isEmpty(); + } + + @Test + void testParticipantParameterGroup_EmptyParticipantIntermediaryParameters() { + final ParticipantSimulatorParameters participantParameters = commonTestData.getParticipantSimulatorParameters(); + participantParameters.setIntermediaryParameters(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } + + @Test + void testParticipantPolicyParameters_NullTopicSinks() { + final ParticipantSimulatorParameters participantParameters = commonTestData.getParticipantSimulatorParameters(); + participantParameters.getIntermediaryParameters().getClampAutomationCompositionTopics().setTopicSinks(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } + + @Test + void testParticipantPolicyParameters_NullTopicSources() { + final ParticipantSimulatorParameters participantParameters = commonTestData.getParticipantSimulatorParameters(); + participantParameters.getIntermediaryParameters().getClampAutomationCompositionTopics().setTopicSources(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/TestListenerUtils.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/TestListenerUtils.java new file mode 100644 index 000000000..f43400259 --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/simulator/main/rest/TestListenerUtils.java @@ -0,0 +1,260 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.simulator.main.rest; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileNotFoundException; +import java.time.Instant; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.onap.policy.clamp.acm.participant.simulator.main.parameters.CommonTestData; +import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition; +import org.onap.policy.clamp.models.acm.concepts.ParticipantUpdates; +import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionStateChange; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionUpdate; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantUpdate; +import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.coder.YamlJsonTranslator; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class TestListenerUtils { + + private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator(); + private static final Coder CODER = new StandardCoder(); + static CommonTestData commonTestData = new CommonTestData(); + private static final Logger LOGGER = LoggerFactory.getLogger(TestListenerUtils.class); + + /** + * Method to create a automationComposition from a yaml file. + * + * @return AutomationComposition automation composition + */ + public static AutomationComposition createAutomationComposition() { + AutomationComposition automationComposition = new AutomationComposition(); + Map elements = new LinkedHashMap<>(); + ToscaServiceTemplate toscaServiceTemplate = testAutomationCompositionRead(); + Map nodeTemplatesMap = + toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates(); + for (Map.Entry toscaInputEntry : nodeTemplatesMap.entrySet()) { + AutomationCompositionElement acElement = new AutomationCompositionElement(); + acElement.setId(UUID.randomUUID()); + + ToscaConceptIdentifier acElementParticipantId = new ToscaConceptIdentifier(); + acElementParticipantId.setName(toscaInputEntry.getKey()); + acElementParticipantId.setVersion(toscaInputEntry.getValue().getVersion()); + acElement.setParticipantId(acElementParticipantId); + acElement.setParticipantType(acElementParticipantId); + + acElement.setDefinition(acElementParticipantId); + acElement.setState(AutomationCompositionState.UNINITIALISED); + acElement.setDescription(toscaInputEntry.getValue().getDescription()); + acElement.setOrderedState(AutomationCompositionOrderedState.UNINITIALISED); + elements.put(acElement.getId(), acElement); + } + automationComposition.setElements(elements); + automationComposition.setName("PMSHInstance0"); + automationComposition.setVersion("1.0.0"); + + ToscaConceptIdentifier definition = new ToscaConceptIdentifier(); + definition.setName("PMSHInstance0"); + definition.setVersion("1.0.0"); + automationComposition.setDefinition(definition); + + return automationComposition; + } + + /** + * Method to create AutomationCompositionStateChange message from the arguments passed. + * + * @param automationCompositionOrderedState automationCompositionOrderedState + * + * @return AutomationCompositionStateChange message + */ + public static AutomationCompositionStateChange createAutomationCompositionStateChangeMsg( + final AutomationCompositionOrderedState automationCompositionOrderedState) { + final AutomationCompositionStateChange acStateChangeMsg = new AutomationCompositionStateChange(); + + ToscaConceptIdentifier automationCompositionId = new ToscaConceptIdentifier("PMSHInstance0", "1.0.0"); + ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_CDS_Blueprint", "1.0.0"); + + acStateChangeMsg.setAutomationCompositionId(automationCompositionId); + acStateChangeMsg.setParticipantId(participantId); + acStateChangeMsg.setTimestamp(Instant.now()); + acStateChangeMsg.setOrderedState(automationCompositionOrderedState); + + return acStateChangeMsg; + } + + /** + * Method to create AutomationCompositionUpdateMsg. + * + * @return AutomationCompositionUpdate message + */ + public static AutomationCompositionUpdate createAutomationCompositionUpdateMsg() { + final AutomationCompositionUpdate acUpdateMsg = new AutomationCompositionUpdate(); + ToscaConceptIdentifier automationCompositionId = new ToscaConceptIdentifier("PMSHInstance0", "1.0.0"); + ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_Policy", "0.0.0"); + + acUpdateMsg.setAutomationCompositionId(automationCompositionId); + acUpdateMsg.setParticipantId(participantId); + acUpdateMsg.setMessageId(UUID.randomUUID()); + acUpdateMsg.setTimestamp(Instant.now()); + + Map elements = new LinkedHashMap<>(); + ToscaServiceTemplate toscaServiceTemplate = testAutomationCompositionRead(); + Map nodeTemplatesMap = + toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates(); + for (Map.Entry toscaInputEntry : nodeTemplatesMap.entrySet()) { + if (ParticipantUtils.checkIfNodeTemplateIsAutomationCompositionElement(toscaInputEntry.getValue(), + toscaServiceTemplate)) { + AutomationCompositionElement acElement = new AutomationCompositionElement(); + acElement.setId(UUID.randomUUID()); + var acParticipantType = + ParticipantUtils.findParticipantType(toscaInputEntry.getValue().getProperties()); + + acElement.setParticipantId(acParticipantType); + acElement.setParticipantType(acParticipantType); + + acElement.setDefinition( + new ToscaConceptIdentifier(toscaInputEntry.getKey(), toscaInputEntry.getValue().getVersion())); + acElement.setState(AutomationCompositionState.UNINITIALISED); + acElement.setDescription(toscaInputEntry.getValue().getDescription()); + acElement.setOrderedState(AutomationCompositionOrderedState.PASSIVE); + elements.put(acElement.getId(), acElement); + } + } + + List participantUpdates = new ArrayList<>(); + for (AutomationCompositionElement element : elements.values()) { + AcmUtils.prepareParticipantUpdate(element, participantUpdates); + } + acUpdateMsg.setParticipantUpdatesList(participantUpdates); + return acUpdateMsg; + } + + /** + * Method to create participantUpdateMsg. + * + * @return ParticipantUpdate message + */ + public static ParticipantUpdate createParticipantUpdateMsg() { + final ParticipantUpdate participantUpdateMsg = new ParticipantUpdate(); + ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_Policy", "1.0.0"); + ToscaConceptIdentifier participantType = + new ToscaConceptIdentifier("org.onap.policy.acm.PolicyAutomationCompositionParticipant", "2.3.1"); + + participantUpdateMsg.setParticipantId(participantId); + participantUpdateMsg.setTimestamp(Instant.now()); + participantUpdateMsg.setParticipantType(participantType); + participantUpdateMsg.setTimestamp(Instant.ofEpochMilli(3000)); + participantUpdateMsg.setMessageId(UUID.randomUUID()); + + ToscaServiceTemplate toscaServiceTemplate = testAutomationCompositionRead(); + // Add policies to the toscaServiceTemplate + List participantDefinitionUpdates = new ArrayList<>(); + for (Map.Entry toscaInputEntry : toscaServiceTemplate.getToscaTopologyTemplate() + .getNodeTemplates().entrySet()) { + if (ParticipantUtils.checkIfNodeTemplateIsAutomationCompositionElement(toscaInputEntry.getValue(), + toscaServiceTemplate)) { + var acParticipantType = + ParticipantUtils.findParticipantType(toscaInputEntry.getValue().getProperties()); + AcmUtils.prepareParticipantDefinitionUpdate(acParticipantType, toscaInputEntry.getKey(), + toscaInputEntry.getValue(), participantDefinitionUpdates, null); + } + } + + participantUpdateMsg.setParticipantDefinitionUpdates(participantDefinitionUpdates); + return participantUpdateMsg; + } + + /** + * Method to create AutomationCompositionUpdate using the arguments passed. + * + * @param jsonFilePath the path of the automation composition content + * + * @return AutomationCompositionUpdate message + * @throws CoderException exception while reading the file to object + */ + public static AutomationCompositionUpdate createParticipantAcUpdateMsgFromJson(String jsonFilePath) + throws CoderException { + AutomationCompositionUpdate automationCompositionUpdateMsg = + CODER.decode(new File(jsonFilePath), AutomationCompositionUpdate.class); + return automationCompositionUpdateMsg; + } + + private static ToscaServiceTemplate testAutomationCompositionRead() { + Set automationCompositionDirectoryContents = + ResourceUtils.getDirectoryContents("src/test/resources/rest/servicetemplates"); + + boolean atLeastOneAutomationCompositionTested = false; + ToscaServiceTemplate toscaServiceTemplate = null; + + for (String automationCompositionFilePath : automationCompositionDirectoryContents) { + if (!automationCompositionFilePath.endsWith(".yaml")) { + continue; + } + atLeastOneAutomationCompositionTested = true; + toscaServiceTemplate = testAutomationCompositionYamlSerialization(automationCompositionFilePath); + } + + assertTrue(atLeastOneAutomationCompositionTested); + return toscaServiceTemplate; + } + + private static ToscaServiceTemplate testAutomationCompositionYamlSerialization( + String automationCompositionFilePath) { + try { + String automationCompositionString = ResourceUtils.getResourceAsString(automationCompositionFilePath); + if (automationCompositionString == null) { + throw new FileNotFoundException(automationCompositionFilePath); + } + + ToscaServiceTemplate serviceTemplate = + yamlTranslator.fromYaml(automationCompositionString, ToscaServiceTemplate.class); + return serviceTemplate; + } catch (FileNotFoundException e) { + LOGGER.error("cannot find YAML file", automationCompositionFilePath); + throw new IllegalArgumentException(e); + } + } +} diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/endtoend/ParticipantSimulatorTest.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/endtoend/ParticipantSimulatorTest.java deleted file mode 100644 index 14f51269a..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/endtoend/ParticipantSimulatorTest.java +++ /dev/null @@ -1,285 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.simulator.endtoend; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; -import java.util.Map; -import java.util.UUID; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.GenericType; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.core.Response; -import org.glassfish.jersey.client.ClientProperties; -import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantState; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate; -import org.onap.policy.clamp.controlloop.models.messages.rest.TypedSimpleResponse; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ControlLoopUpdateListener; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler; -import org.onap.policy.clamp.controlloop.participant.simulator.main.parameters.CommonTestData; -import org.onap.policy.clamp.controlloop.participant.simulator.main.rest.AbstractRestController; -import org.onap.policy.clamp.controlloop.participant.simulator.main.rest.TestListenerUtils; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.gson.GsonMessageBodyHandler; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@ExtendWith(SpringExtension.class) -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -@TestPropertySource(locations = {"classpath:application_test.properties"}) -class ParticipantSimulatorTest { - - private static final String PARTICIPANTS_ENDPOINT = "participants"; - private static final String ELEMENTS_ENDPOINT = "elements"; - private static final CommInfrastructure INFRA = CommInfrastructure.NOOP; - private static final String TOPIC = "my-topic"; - - @Value("${spring.security.user.name}") - private String user; - - @Value("${spring.security.user.password}") - private String password; - - @LocalServerPort - private int randomServerPort; - - @Autowired - private ParticipantIntermediaryApi participantIntermediaryApi; - - @Autowired - private ParticipantHandler participantHandler; - - private static final Object lockit = new Object(); - private boolean check = false; - - private void setUp() throws Exception { - synchronized (lockit) { - if (!check) { - check = true; - ControlLoopUpdateListener clUpdateListener = new ControlLoopUpdateListener(participantHandler); - - ControlLoopUpdate controlLoopUpdateMsg = TestListenerUtils.createControlLoopUpdateMsg(); - clUpdateListener.onTopicEvent(INFRA, TOPIC, null, controlLoopUpdateMsg); - - } - } - } - - private String getPath(String path) { - return "http://localhost:" + randomServerPort + "/onap/participantsim/v2/" + path; - } - - void testSwagger(String endPoint) { - final Client client = ClientBuilder.newBuilder().build(); - - client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true"); - client.register(GsonMessageBodyHandler.class); - client.register(HttpAuthenticationFeature.basic(user, password)); - - final WebTarget webTarget = client.target(getPath("api-docs")); - - Response response = webTarget.request(MediaType.APPLICATION_JSON).get(); - - assertThat(response.getStatus()).isEqualTo(200); - assertTrue(response.readEntity(String.class).contains("/onap/participantsim/v2/" + endPoint)); - } - - @Test - void testEndParticipatsSwagger() { - testSwagger(PARTICIPANTS_ENDPOINT); - } - - @Test - void testElementsSwagger() { - testSwagger(ELEMENTS_ENDPOINT); - } - - @Test - void testProducerYaml() { - final Client client = ClientBuilder.newBuilder().build(); - - client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true"); - client.register(GsonMessageBodyHandler.class); - client.register(HttpAuthenticationFeature.basic(user, password)); - - String path = getPath(PARTICIPANTS_ENDPOINT + "/org.onap.PM_CDS_Blueprint/1"); - final WebTarget webTarget = client.target(path); - - Response response = webTarget.request("application/yaml").get(); - - assertThat(response.getStatus()).isEqualTo(200); - } - - @Test - void testQuery_Unauthorized() throws Exception { - String path = PARTICIPANTS_ENDPOINT + "/org.onap.PM_CDS_Blueprint/1"; - - Response response = performRequest(path, true, null).get(); - assertThat(response.getStatus()).isEqualTo(200); - - // unauthorized call - response = performRequest(path, false, null).get(); - assertThat(response.getStatus()).isEqualTo(401); - } - - private Invocation.Builder performRequest(String endpoint, boolean includeAuth, UUID uuid) { - final Client client = ClientBuilder.newBuilder().build(); - - client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true"); - client.register(GsonMessageBodyHandler.class); - if (includeAuth) { - client.register(HttpAuthenticationFeature.basic(user, password)); - } - Invocation.Builder builder = client.target(getPath(endpoint)).request(MediaType.APPLICATION_JSON); - if (uuid != null) { - builder = builder.header(AbstractRestController.REQUEST_ID_NAME, uuid.toString()); - } - return builder; - } - - private Response performGet(String endpoint, UUID uuid) throws Exception { - return performRequest(endpoint, true, uuid).get(); - } - - @Test - void testQueryParticipants() throws Exception { - Participant participant = new Participant(); - ToscaConceptIdentifier participantId = CommonTestData.getParticipantId(); - participant.setDefinition(participantId); - participant.setName(participantId.getName()); - participant.setVersion(participantId.getVersion()); - UUID uuid = UUID.randomUUID(); - - // GET REST call for querying the participants - Response response = performGet( - PARTICIPANTS_ENDPOINT + "/" + participant.getKey().getName() + "/" + participant.getKey().getVersion(), - uuid); - checkResponseEntity(response, 200, uuid); - - Participant[] returnValue = response.readEntity(Participant[].class); - assertThat(returnValue).hasSize(1); - // Verify the result of GET participants with what is stored - assertEquals(participant.getDefinition(), returnValue[0].getDefinition()); - } - - private void checkResponseEntity(Response response, int status, UUID uuid) { - assertThat(response.getStatus()).isEqualTo(status); - assertThat(getHeader(response.getHeaders(), AbstractRestController.VERSION_MINOR_NAME)).isEqualTo("0"); - assertThat(getHeader(response.getHeaders(), AbstractRestController.VERSION_PATCH_NAME)).isEqualTo("0"); - assertThat(getHeader(response.getHeaders(), AbstractRestController.VERSION_LATEST_NAME)).isEqualTo("1.0.0"); - assertThat(getHeader(response.getHeaders(), AbstractRestController.REQUEST_ID_NAME)).isEqualTo(uuid.toString()); - } - - private String getHeader(MultivaluedMap httpHeaders, String param) { - List list = httpHeaders.get(param); - assertThat(list).hasSize(1); - assertThat(list.get(0)).isNotNull(); - return (String) list.get(0); - } - - @Test - void testQueryControlLoopElements() throws Exception { - setUp(); - UUID uuid = UUID.randomUUID(); - ToscaConceptIdentifier participantId = CommonTestData.getParticipantId(); - - // GET REST call for querying the controlLoop elements - Response response = - performGet(ELEMENTS_ENDPOINT + "/" + participantId.getName() + "/" + participantId.getVersion(), uuid); - checkResponseEntity(response, 200, uuid); - - Map returnValue = response.readEntity(Map.class); - // Verify the result of GET controlloop elements with what is stored - assertThat(returnValue).isEmpty(); - } - - private Response performPut(String endpoint, final Entity entity, UUID uuid) throws Exception { - return performRequest(endpoint, true, uuid).put(entity); - } - - @Test - void testUpdateParticipant() throws Exception { - setUp(); - List participants = participantIntermediaryApi.getParticipants( - CommonTestData.getParticipantId().getName(), CommonTestData.getParticipantId().getVersion()); - assertEquals(ParticipantState.UNKNOWN, participants.get(0).getParticipantState()); - // Change the state of the participant to PASSIVE from UNKNOWN - participants.get(0).setParticipantState(ParticipantState.PASSIVE); - UUID uuid = UUID.randomUUID(); - - // PUT REST call for updating Participant - Response response = performPut(PARTICIPANTS_ENDPOINT, Entity.json(participants.get(0)), uuid); - checkResponseEntity(response, 200, uuid); - - TypedSimpleResponse resp = - response.readEntity(new GenericType>() {}); - assertNotNull(resp.getResponse()); - // Verify the response and state returned by PUT REST call for updating participants - assertEquals(participants.get(0).getDefinition(), resp.getResponse().getDefinition()); - assertEquals(ParticipantState.PASSIVE, resp.getResponse().getParticipantState()); - } - - @Test - void testUpdateControlLoopElement() throws Exception { - setUp(); - ControlLoop controlLoop = TestListenerUtils.createControlLoop(); - Map controlLoopElements = participantIntermediaryApi.getControlLoopElements( - controlLoop.getDefinition().getName(), controlLoop.getDefinition().getVersion()); - - UUID uuid = controlLoopElements.keySet().iterator().next(); - ControlLoopElement controlLoopElement = controlLoopElements.get(uuid); - - controlLoopElement.setOrderedState(ControlLoopOrderedState.PASSIVE); - // PUT REST call for updating ControlLoopElement - Response response = performPut(ELEMENTS_ENDPOINT, Entity.json(controlLoopElement), uuid); - checkResponseEntity(response, 200, uuid); - - TypedSimpleResponse resp = - response.readEntity(new GenericType>() {}); - assertNotNull(resp.getResponse()); - // Verify the response and state returned by PUT REST call for updating participants - assertEquals(controlLoopElement.getDefinition(), resp.getResponse().getDefinition()); - assertEquals(ControlLoopOrderedState.PASSIVE, resp.getResponse().getOrderedState()); - } -} diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/handler/ControlLoopElementHandlerTest.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/handler/ControlLoopElementHandlerTest.java deleted file mode 100644 index b38adbc5c..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/handler/ControlLoopElementHandlerTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.simulator.main.handler; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.mockito.Mockito.when; - -import java.util.UUID; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; - -class ControlLoopElementHandlerTest { - - private static final String ID_NAME = "org.onap.PM_CDS_Blueprint"; - private static final String ID_VERSION = "1.0.1"; - private static final UUID controlLoopElementId = UUID.randomUUID(); - private static final ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); - - @Test - void testSimulatorHandlerExceptions() throws PfModelException { - ControlLoopElementHandler handler = getTestingHandler(); - - assertDoesNotThrow(() -> handler - .controlLoopElementStateChange(controlLoopId, - controlLoopElementId, - ControlLoopState.UNINITIALISED, - ControlLoopOrderedState.PASSIVE)); - - assertDoesNotThrow(() -> handler - .controlLoopElementStateChange(controlLoopId, - controlLoopElementId, - ControlLoopState.RUNNING, - ControlLoopOrderedState.UNINITIALISED)); - - assertDoesNotThrow(() -> handler - .controlLoopElementStateChange(controlLoopId, - controlLoopElementId, - ControlLoopState.PASSIVE, - ControlLoopOrderedState.RUNNING)); - var element = getTestingClElement(); - var clElementDefinition = Mockito.mock(ToscaNodeTemplate.class); - - assertDoesNotThrow(() -> handler - .controlLoopElementUpdate(controlLoopId, element, clElementDefinition)); - - assertDoesNotThrow(() -> handler - .handleStatistics(controlLoopElementId)); - } - - ControlLoopElementHandler getTestingHandler() { - var handler = new ControlLoopElementHandler(); - var intermediaryApi = Mockito.mock(ParticipantIntermediaryApi.class); - var element = getTestingClElement(); - when(intermediaryApi.getControlLoopElement(controlLoopElementId)).thenReturn(element); - handler.setIntermediaryApi(intermediaryApi); - return handler; - } - - ControlLoopElement getTestingClElement() { - var element = new ControlLoopElement(); - element.setDefinition(controlLoopId); - element.setDescription("Description"); - element.setId(controlLoopElementId); - element.setOrderedState(ControlLoopOrderedState.UNINITIALISED); - element.setParticipantId(controlLoopId); - element.setState(ControlLoopState.UNINITIALISED); - var template = Mockito.mock(ToscaServiceTemplate.class); - element.setToscaServiceTemplateFragment(template); - return element; - } - -} diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/CommonTestData.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/CommonTestData.java deleted file mode 100644 index 9c41c8bcb..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/CommonTestData.java +++ /dev/null @@ -1,140 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.simulator.main.parameters; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import org.onap.policy.common.endpoints.parameters.TopicParameters; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; - -/** - * Class to hold/create all parameters for test cases. - */ -public class CommonTestData { - public static final String PARTICIPANT_GROUP_NAME = "ControlLoopParticipantGroup"; - public static final String DESCRIPTION = "Participant description"; - public static final long TIME_INTERVAL = 2000; - public static final List TOPIC_PARAMS = Arrays.asList(getTopicParams()); - - public static final Coder CODER = new StandardCoder(); - - /** - * Get ParticipantSimulatorParameters. - * - * @return ParticipantSimulatorParameters - */ - public ParticipantSimulatorParameters getParticipantSimulatorParameters() { - try { - return CODER.convert(getParticipantParameterGroupMap(PARTICIPANT_GROUP_NAME), - ParticipantSimulatorParameters.class); - } catch (final CoderException e) { - throw new RuntimeException("cannot create ParticipantSimulatorParameters from map", e); - } - } - - /** - * Returns a property map for a ApexStarterParameterGroup map for test cases. - * - * @param name name of the parameters - * - * @return a property map suitable for constructing an object - */ - public Map getParticipantParameterGroupMap(final String name) { - final Map map = new TreeMap<>(); - - map.put("intermediaryParameters", getIntermediaryParametersMap(false)); - return map; - } - - /** - * Returns a property map for a intermediaryParameters map for test cases. - * - * @param isEmpty boolean value to represent that object created should be empty or not - * @return a property map suitable for constructing an object - */ - public Map getIntermediaryParametersMap(final boolean isEmpty) { - final Map map = new TreeMap<>(); - if (!isEmpty) { - map.put("name", "Participant parameters"); - map.put("reportingTimeIntervalMs", TIME_INTERVAL); - map.put("description", DESCRIPTION); - map.put("participantId", getParticipantId()); - map.put("participantType", getParticipantId()); - map.put("clampControlLoopTopics", getTopicParametersMap(false)); - } - - return map; - } - - /** - * Returns a property map for a TopicParameters map for test cases. - * - * @param isEmpty boolean value to represent that object created should be empty or not - * @return a property map suitable for constructing an object - */ - public Map getTopicParametersMap(final boolean isEmpty) { - final Map map = new TreeMap<>(); - if (!isEmpty) { - map.put("topicSources", TOPIC_PARAMS); - map.put("topicSinks", TOPIC_PARAMS); - } - return map; - } - - /** - * Returns topic parameters for test cases. - * - * @return topic parameters - */ - public static TopicParameters getTopicParams() { - final TopicParameters topicParams = new TopicParameters(); - topicParams.setTopic("POLICY-CLRUNTIME-PARTICIPANT"); - topicParams.setTopicCommInfrastructure("dmaap"); - topicParams.setServers(Arrays.asList("localhost")); - return topicParams; - } - - /** - * Returns participantId for test cases. - * - * @return participant Id - */ - public static ToscaConceptIdentifier getParticipantId() { - final ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_CDS_Blueprint", "1.0.0"); - return participantId; - } - - /** - * Nulls out a field within a JSON string. - * - * @param json JSON string - * @param field field to be nulled out - * @return a new JSON string with the field nulled out - */ - public String nullifyField(String json, String field) { - return json.replace(field + "\"", field + "\":null, \"" + field + "Xxx\""); - } -} diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/TestParticipantSimulatorParameters.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/TestParticipantSimulatorParameters.java deleted file mode 100644 index 3c1d1c2a3..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/TestParticipantSimulatorParameters.java +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.simulator.main.parameters; - -import static org.assertj.core.api.Assertions.assertThat; - -import javax.validation.Validation; -import javax.validation.ValidatorFactory; -import org.junit.jupiter.api.Test; - -/** - * Class to perform unit test of {@link ParticipantParameterGroup}. - */ -class TestParticipantSimulatorParameters { - private CommonTestData commonTestData = new CommonTestData(); - private ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); - - @Test - void testParticipantParameterGroup() { - final ParticipantSimulatorParameters participantParameters = commonTestData.getParticipantSimulatorParameters(); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isEmpty(); - } - - @Test - void testParticipantParameterGroup_EmptyParticipantIntermediaryParameters() { - final ParticipantSimulatorParameters participantParameters = commonTestData.getParticipantSimulatorParameters(); - participantParameters.setIntermediaryParameters(null); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); - } - - @Test - void testParticipantPolicyParameters_NullTopicSinks() { - final ParticipantSimulatorParameters participantParameters = commonTestData.getParticipantSimulatorParameters(); - participantParameters.getIntermediaryParameters().getClampControlLoopTopics().setTopicSinks(null); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); - } - - @Test - void testParticipantPolicyParameters_NullTopicSources() { - final ParticipantSimulatorParameters participantParameters = commonTestData.getParticipantSimulatorParameters(); - participantParameters.getIntermediaryParameters().getClampControlLoopTopics().setTopicSources(null); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); - } -} diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/TestListenerUtils.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/TestListenerUtils.java deleted file mode 100644 index 9f6a31e28..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/TestListenerUtils.java +++ /dev/null @@ -1,257 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.simulator.main.rest; - -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.FileNotFoundException; -import java.time.Instant; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.onap.policy.clamp.controlloop.common.utils.CommonUtils; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUpdates; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUtils; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopStateChange; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate; -import org.onap.policy.clamp.controlloop.participant.simulator.main.parameters.CommonTestData; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.onap.policy.common.utils.coder.YamlJsonTranslator; -import org.onap.policy.common.utils.resources.ResourceUtils; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public final class TestListenerUtils { - - private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator(); - private static final Coder CODER = new StandardCoder(); - static CommonTestData commonTestData = new CommonTestData(); - private static final Logger LOGGER = LoggerFactory.getLogger(TestListenerUtils.class); - - /** - * Method to create a controlLoop from a yaml file. - * - * @return ControlLoop controlloop - */ - public static ControlLoop createControlLoop() { - ControlLoop controlLoop = new ControlLoop(); - Map elements = new LinkedHashMap<>(); - ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead(); - Map nodeTemplatesMap = - toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates(); - for (Map.Entry toscaInputEntry : nodeTemplatesMap.entrySet()) { - ControlLoopElement clElement = new ControlLoopElement(); - clElement.setId(UUID.randomUUID()); - - ToscaConceptIdentifier clElementParticipantId = new ToscaConceptIdentifier(); - clElementParticipantId.setName(toscaInputEntry.getKey()); - clElementParticipantId.setVersion(toscaInputEntry.getValue().getVersion()); - clElement.setParticipantId(clElementParticipantId); - clElement.setParticipantType(clElementParticipantId); - - clElement.setDefinition(clElementParticipantId); - clElement.setState(ControlLoopState.UNINITIALISED); - clElement.setDescription(toscaInputEntry.getValue().getDescription()); - clElement.setOrderedState(ControlLoopOrderedState.UNINITIALISED); - elements.put(clElement.getId(), clElement); - } - controlLoop.setElements(elements); - controlLoop.setName("PMSHInstance0"); - controlLoop.setVersion("1.0.0"); - - ToscaConceptIdentifier definition = new ToscaConceptIdentifier(); - definition.setName("PMSHInstance0"); - definition.setVersion("1.0.0"); - controlLoop.setDefinition(definition); - - return controlLoop; - } - - /** - * Method to create ControlLoopStateChange message from the arguments passed. - * - * @param controlLoopOrderedState controlLoopOrderedState - * - * @return ControlLoopStateChange message - */ - public static ControlLoopStateChange createControlLoopStateChangeMsg( - final ControlLoopOrderedState controlLoopOrderedState) { - final ControlLoopStateChange clStateChangeMsg = new ControlLoopStateChange(); - - ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier("PMSHInstance0", "1.0.0"); - ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_CDS_Blueprint", "1.0.0"); - - clStateChangeMsg.setControlLoopId(controlLoopId); - clStateChangeMsg.setParticipantId(participantId); - clStateChangeMsg.setTimestamp(Instant.now()); - clStateChangeMsg.setOrderedState(controlLoopOrderedState); - - return clStateChangeMsg; - } - - /** - * Method to create ControlLoopUpdateMsg. - * - * @return ControlLoopUpdate message - */ - public static ControlLoopUpdate createControlLoopUpdateMsg() { - final ControlLoopUpdate clUpdateMsg = new ControlLoopUpdate(); - ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier("PMSHInstance0", "1.0.0"); - ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_Policy", "0.0.0"); - - clUpdateMsg.setControlLoopId(controlLoopId); - clUpdateMsg.setParticipantId(participantId); - clUpdateMsg.setMessageId(UUID.randomUUID()); - clUpdateMsg.setTimestamp(Instant.now()); - - Map elements = new LinkedHashMap<>(); - ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead(); - Map nodeTemplatesMap = - toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates(); - for (Map.Entry toscaInputEntry : nodeTemplatesMap.entrySet()) { - if (ParticipantUtils.checkIfNodeTemplateIsControlLoopElement(toscaInputEntry.getValue(), - toscaServiceTemplate)) { - ControlLoopElement clElement = new ControlLoopElement(); - clElement.setId(UUID.randomUUID()); - var clParticipantType = - ParticipantUtils.findParticipantType(toscaInputEntry.getValue().getProperties()); - - clElement.setParticipantId(clParticipantType); - clElement.setParticipantType(clParticipantType); - - clElement.setDefinition( - new ToscaConceptIdentifier(toscaInputEntry.getKey(), toscaInputEntry.getValue().getVersion())); - clElement.setState(ControlLoopState.UNINITIALISED); - clElement.setDescription(toscaInputEntry.getValue().getDescription()); - clElement.setOrderedState(ControlLoopOrderedState.PASSIVE); - elements.put(clElement.getId(), clElement); - } - } - - List participantUpdates = new ArrayList<>(); - for (ControlLoopElement element : elements.values()) { - CommonUtils.prepareParticipantUpdate(element, participantUpdates); - } - clUpdateMsg.setParticipantUpdatesList(participantUpdates); - return clUpdateMsg; - } - - /** - * Method to create participantUpdateMsg. - * - * @return ParticipantUpdate message - */ - public static ParticipantUpdate createParticipantUpdateMsg() { - final ParticipantUpdate participantUpdateMsg = new ParticipantUpdate(); - ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_Policy", "1.0.0"); - ToscaConceptIdentifier participantType = - new ToscaConceptIdentifier("org.onap.policy.controlloop.PolicyControlLoopParticipant", "2.3.1"); - - participantUpdateMsg.setParticipantId(participantId); - participantUpdateMsg.setTimestamp(Instant.now()); - participantUpdateMsg.setParticipantType(participantType); - participantUpdateMsg.setTimestamp(Instant.ofEpochMilli(3000)); - participantUpdateMsg.setMessageId(UUID.randomUUID()); - - ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead(); - // Add policies to the toscaServiceTemplate - List participantDefinitionUpdates = new ArrayList<>(); - for (Map.Entry toscaInputEntry : toscaServiceTemplate.getToscaTopologyTemplate() - .getNodeTemplates().entrySet()) { - if (ParticipantUtils.checkIfNodeTemplateIsControlLoopElement(toscaInputEntry.getValue(), - toscaServiceTemplate)) { - var clParticipantType = - ParticipantUtils.findParticipantType(toscaInputEntry.getValue().getProperties()); - CommonUtils.prepareParticipantDefinitionUpdate(clParticipantType, toscaInputEntry.getKey(), - toscaInputEntry.getValue(), participantDefinitionUpdates, null); - } - } - - participantUpdateMsg.setParticipantDefinitionUpdates(participantDefinitionUpdates); - return participantUpdateMsg; - } - - /** - * Method to create ControlLoopUpdate using the arguments passed. - * - * @param jsonFilePath the path of the controlloop content - * - * @return ControlLoopUpdate message - * @throws CoderException exception while reading the file to object - */ - public static ControlLoopUpdate createParticipantClUpdateMsgFromJson(String jsonFilePath) throws CoderException { - ControlLoopUpdate controlLoopUpdateMsg = CODER.decode(new File(jsonFilePath), ControlLoopUpdate.class); - return controlLoopUpdateMsg; - } - - private static ToscaServiceTemplate testControlLoopRead() { - Set controlLoopDirectoryContents = - ResourceUtils.getDirectoryContents("src/test/resources/rest/servicetemplates"); - - boolean atLeastOneControlLoopTested = false; - ToscaServiceTemplate toscaServiceTemplate = null; - - for (String controlLoopFilePath : controlLoopDirectoryContents) { - if (!controlLoopFilePath.endsWith(".yaml")) { - continue; - } - atLeastOneControlLoopTested = true; - toscaServiceTemplate = testControlLoopYamlSerialization(controlLoopFilePath); - } - - assertTrue(atLeastOneControlLoopTested); - return toscaServiceTemplate; - } - - private static ToscaServiceTemplate testControlLoopYamlSerialization(String controlLoopFilePath) { - try { - String controlLoopString = ResourceUtils.getResourceAsString(controlLoopFilePath); - if (controlLoopString == null) { - throw new FileNotFoundException(controlLoopFilePath); - } - - ToscaServiceTemplate serviceTemplate = - yamlTranslator.fromYaml(controlLoopString, ToscaServiceTemplate.class); - return serviceTemplate; - } catch (FileNotFoundException e) { - LOGGER.error("cannot find YAML file", controlLoopFilePath); - throw new IllegalArgumentException(e); - } - } -} diff --git a/participant/participant-impl/participant-impl-simulator/src/test/resources/application_test.properties b/participant/participant-impl/participant-impl-simulator/src/test/resources/application_test.properties index a4a1f99e5..ccc54581e 100644 --- a/participant/participant-impl/participant-impl-simulator/src/test/resources/application_test.properties +++ b/participant/participant-impl/participant-impl-simulator/src/test/resources/application_test.properties @@ -16,10 +16,10 @@ participant.intermediaryParameters.participantId.name=org.onap.PM_CDS_Blueprint participant.intermediaryParameters.participantId.version=1.0.0 participant.intermediaryParameters.participantType.name=org.onap.PM_CDS_Blueprint participant.intermediaryParameters.participantType.version=1.0.0 -participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].topic=POLICY-CLRUNTIME-PARTICIPANT -participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].servers[0]=localhost -participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].topicCommInfrastructure=dmaap -participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].fetchTimeout=15000 -participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].topic=POLICY-CLRUNTIME-PARTICIPANT -participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].servers[0]=localhost -participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].topicCommInfrastructure=dmaap +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSources[0].topic=POLICY-ACRUNTIME-PARTICIPANT +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSources[0].servers[0]=localhost +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSources[0].topicCommInfrastructure=dmaap +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSources[0].fetchTimeout=15000 +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSinks[0].topic=POLICY-ACRUNTIME-PARTICIPANT +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSinks[0].servers[0]=localhost +participant.intermediaryParameters.clampAutomationCompositionTopics.topicSinks[0].topicCommInfrastructure=dmaap diff --git a/participant/participant-impl/participant-impl-simulator/src/test/resources/rest/servicetemplates/pm_automation_composition_tosca.yaml b/participant/participant-impl/participant-impl-simulator/src/test/resources/rest/servicetemplates/pm_automation_composition_tosca.yaml new file mode 100644 index 000000000..6e34c7cce --- /dev/null +++ b/participant/participant-impl/participant-impl-simulator/src/test/resources/rest/servicetemplates/pm_automation_composition_tosca.yaml @@ -0,0 +1,164 @@ +tosca_definitions_version: tosca_simple_yaml_1_3 +data_types: + onap.datatypes.ToscaConceptIdentifier: + derived_from: tosca.datatypes.Root + properties: + name: + type: string + required: true + version: + type: string + required: true +node_types: + org.onap.policy.clamp.acm.Participant: + version: 1.0.1 + derived_from: tosca.nodetypes.Root + properties: + provider: + type: string + requred: false + org.onap.policy.clamp.acm.AutomationCompositionElement: + version: 1.0.1 + derived_from: tosca.nodetypes.Root + properties: + provider: + type: string + requred: false + participantType: + type: onap.datatypes.ToscaConceptIdentifier + requred: true + startPhase: + type: integer + required: false + constraints: + - greater-or-equal: 0 + metadata: + common: true + description: A value indicating the start phase in which this automation composition element will be started, the + first start phase is zero. Automation Composition Elements are started in their start_phase order and stopped + in reverse start phase order. Automation Composition Elements with the same start phase are started and + stopped simultaneously + org.onap.policy.clamp.acm.AutomationComposition: + version: 1.0.1 + derived_from: tosca.nodetypes.Root + properties: + provider: + type: string + requred: false + elements: + type: list + required: true + entry_schema: + type: onap.datatypes.ToscaConceptIdentifier + org.onap.policy.clamp.acm.DCAEMicroserviceAutomationCompositionElement: + version: 1.0.1 + derived_from: org.onap.policy.clamp.acm.AutomationCompositionElement + properties: + dcae_blueprint_id: + type: onap.datatypes.ToscaConceptIdentifier + requred: true + org.onap.policy.clamp.acm.PolicyTypeAutomationCompositionElement: + version: 1.0.1 + derived_from: org.onap.policy.clamp.acm.AutomationCompositionElement + properties: + policy_type_id: + type: onap.datatypes.ToscaConceptIdentifier + requred: true + org.onap.policy.clamp.acm.CDSAutomationCompositionElement: + version: 1.0.1 + derived_from: org.onap.policy.clamp.acm.AutomationCompositionElement + properties: + cds_blueprint_id: + type: onap.datatypes.ToscaConceptIdentifier + requred: true +topology_template: + node_templates: + org.onap.dcae.acm.DCAEMicroserviceAutomationCompositionParticipant: + version: 2.3.4 + type: org.onap.policy.clamp.acm.Participant + type_version: 1.0.1 + description: Participant for DCAE microservices + properties: + provider: ONAP + org.onap.policy.acm.PolicyAutomationCompositionParticipant: + version: 2.3.1 + type: org.onap.policy.clamp.acm.Participant + type_version: 1.0.1 + description: Participant for DCAE microservices + properties: + provider: ONAP + org.onap.ccsdk.cds.acm.CdsAutomationCompositionParticipant: + version: 2.2.1 + type: org.onap.policy.clamp.acm.Participant + type_version: 1.0.1 + description: Participant for DCAE microservices + properties: + provider: ONAP + org.onap.domain.pmsh.PMSH_DCAEMicroservice: + version: 1.2.3 + type: org.onap.policy.clamp.acm.DCAEMicroserviceAutomationCompositionElement + type_version: 1.0.0 + description: Automation composition element for the DCAE microservice for Performance Management Subscription Handling + properties: + provider: Ericsson + participantType: + name: org.onap.dcae.acm.DCAEMicroserviceAutomationCompositionParticipant + version: 2.3.4 + dcae_blueprint_id: + name: org.onap.dcae.blueprints.PMSHBlueprint + version: 1.0.0 + org.onap.domain.pmsh.PMSH_MonitoringPolicyAutomationCompositionElement: + version: 1.2.3 + type: org.onap.policy.clamp.acm.PolicyTypeAutomationCompositionElement + type_version: 1.0.0 + description: Automation composition element for the monitoring policy for Performance Management Subscription Handling + properties: + provider: Ericsson + participantType: + name: org.onap.policy.acm.PolicyAutomationCompositionParticipant + version: 2.3.1 + policy_type_id: + name: onap.policies.monitoring.pm-subscription-handler + version: 1.0.0 + org.onap.domain.pmsh.PMSH_OperationalPolicyAutomationCompositionElement: + version: 1.2.3 + type: org.onap.policy.clamp.acm.PolicyTypeAutomationCompositionElement + type_version: 1.0.0 + description: Automation composition element for the operational policy for Performance Management Subscription Handling + properties: + provider: Ericsson + participantType: + name: org.onap.policy.acm.PolicyAutomationCompositionParticipant + version: 2.3.1 + policy_type_id: + name: onap.policies.operational.pm-subscription-handler + version: 1.0.0 + org.onap.domain.pmsh.PMSH_CDS_AutomationCompositionElement: + version: 1.2.3 + type: org.onap.policy.clamp.acm.AutomationCompositionElement + type_version: 1.0.0 + description: Automation composition element for CDS for Performance Management Subscription Handling + properties: + provider: Ericsson + participantType: + name: org.onap.PM_CDS_Blueprint + version: 1.0.0 + cds_blueprint_id: + name: org.onap.ccsdk.cds.PMSHCdsBlueprint + version: 1.0.0 + org.onap.domain.pmsh.PMSHAutomationCompositionDefinition: + version: 1.2.3 + type: org.onap.policy.clamp.acm.AutomationComposition + type_version: 1.0.0 + description: Automation composition for Performance Management Subscription Handling + properties: + provider: Ericsson + elements: + - name: org.onap.domain.pmsh.PMSH_DCAEMicroservice + version: 1.2.3 + - name: org.onap.domain.pmsh.PMSH_MonitoringPolicyAutomationCompositionElement + version: 1.2.3 + - name: org.onap.domain.pmsh.PMSH_OperationalPolicyAutomationCompositionElement + version: 1.2.3 + - name: org.onap.domain.pmsh.PMSH_CDS_AutomationCompositionElement + version: 1.2.3 diff --git a/participant/participant-impl/participant-impl-simulator/src/test/resources/rest/servicetemplates/pm_control_loop_tosca.yaml b/participant/participant-impl/participant-impl-simulator/src/test/resources/rest/servicetemplates/pm_control_loop_tosca.yaml deleted file mode 100644 index 21d20a8ee..000000000 --- a/participant/participant-impl/participant-impl-simulator/src/test/resources/rest/servicetemplates/pm_control_loop_tosca.yaml +++ /dev/null @@ -1,164 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_3 -data_types: - onap.datatypes.ToscaConceptIdentifier: - derived_from: tosca.datatypes.Root - properties: - name: - type: string - required: true - version: - type: string - required: true -node_types: - org.onap.policy.clamp.controlloop.Participant: - version: 1.0.1 - derived_from: tosca.nodetypes.Root - properties: - provider: - type: string - requred: false - org.onap.policy.clamp.controlloop.ControlLoopElement: - version: 1.0.1 - derived_from: tosca.nodetypes.Root - properties: - provider: - type: string - requred: false - participantType: - type: onap.datatypes.ToscaConceptIdentifier - requred: true - startPhase: - type: integer - required: false - constraints: - - greater-or-equal: 0 - metadata: - common: true - description: A value indicating the start phase in which this control loop element will be started, the - first start phase is zero. Control Loop Elements are started in their start_phase order and stopped - in reverse start phase order. Control Loop Elements with the same start phase are started and - stopped simultaneously - org.onap.policy.clamp.controlloop.ControlLoop: - version: 1.0.1 - derived_from: tosca.nodetypes.Root - properties: - provider: - type: string - requred: false - elements: - type: list - required: true - entry_schema: - type: onap.datatypes.ToscaConceptIdentifier - org.onap.policy.clamp.controlloop.DCAEMicroserviceControlLoopElement: - version: 1.0.1 - derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement - properties: - dcae_blueprint_id: - type: onap.datatypes.ToscaConceptIdentifier - requred: true - org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement: - version: 1.0.1 - derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement - properties: - policy_type_id: - type: onap.datatypes.ToscaConceptIdentifier - requred: true - org.onap.policy.clamp.controlloop.CDSControlLoopElement: - version: 1.0.1 - derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement - properties: - cds_blueprint_id: - type: onap.datatypes.ToscaConceptIdentifier - requred: true -topology_template: - node_templates: - org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant: - version: 2.3.4 - type: org.onap.policy.clamp.controlloop.Participant - type_version: 1.0.1 - description: Participant for DCAE microservices - properties: - provider: ONAP - org.onap.policy.controlloop.PolicyControlLoopParticipant: - version: 2.3.1 - type: org.onap.policy.clamp.controlloop.Participant - type_version: 1.0.1 - description: Participant for DCAE microservices - properties: - provider: ONAP - org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant: - version: 2.2.1 - type: org.onap.policy.clamp.controlloop.Participant - type_version: 1.0.1 - description: Participant for DCAE microservices - properties: - provider: ONAP - org.onap.domain.pmsh.PMSH_DCAEMicroservice: - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.DCAEMicroserviceControlLoopElement - type_version: 1.0.0 - description: Control loop element for the DCAE microservice for Performance Management Subscription Handling - properties: - provider: Ericsson - participantType: - name: org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant - version: 2.3.4 - dcae_blueprint_id: - name: org.onap.dcae.blueprints.PMSHBlueprint - version: 1.0.0 - org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement: - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement - type_version: 1.0.0 - description: Control loop element for the monitoring policy for Performance Management Subscription Handling - properties: - provider: Ericsson - participantType: - name: org.onap.policy.controlloop.PolicyControlLoopParticipant - version: 2.3.1 - policy_type_id: - name: onap.policies.monitoring.pm-subscription-handler - version: 1.0.0 - org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement: - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement - type_version: 1.0.0 - description: Control loop element for the operational policy for Performance Management Subscription Handling - properties: - provider: Ericsson - participantType: - name: org.onap.policy.controlloop.PolicyControlLoopParticipant - version: 2.3.1 - policy_type_id: - name: onap.policies.operational.pm-subscription-handler - version: 1.0.0 - org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement: - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.ControlLoopElement - type_version: 1.0.0 - description: Control loop element for CDS for Performance Management Subscription Handling - properties: - provider: Ericsson - participantType: - name: org.onap.PM_CDS_Blueprint - version: 1.0.0 - cds_blueprint_id: - name: org.onap.ccsdk.cds.PMSHCdsBlueprint - version: 1.0.0 - org.onap.domain.pmsh.PMSHControlLoopDefinition: - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.ControlLoop - type_version: 1.0.0 - description: Control loop for Performance Management Subscription Handling - properties: - provider: Ericsson - elements: - - name: org.onap.domain.pmsh.PMSH_DCAEMicroservice - version: 1.2.3 - - name: org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement - version: 1.2.3 - - name: org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement - version: 1.2.3 - - name: org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement - version: 1.2.3 diff --git a/participant/participant-intermediary/pom.xml b/participant/participant-intermediary/pom.xml index c6078360e..936d26b76 100644 --- a/participant/participant-intermediary/pom.xml +++ b/participant/participant-intermediary/pom.xml @@ -30,7 +30,7 @@ policy-clamp-participant-intermediary ${project.artifactId} - Common intermediary library for managing DMaaP participant messaging and holding participant and control - loop state + Common intermediary library for managing DMaaP participant messaging and holding participant and + Automation Composition state diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/AutomationCompositionElementListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/AutomationCompositionElementListener.java new file mode 100644 index 000000000..9affd5751 --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/AutomationCompositionElementListener.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.api; + +import java.util.UUID; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; + +/** + * This interface is implemented by participant implementations to receive updates on automation composition elements. + */ +public interface AutomationCompositionElementListener { + /** + * Handle a automation composition element state change. + * + * @param automationCompositionElementId the ID of the automation composition element + * @param currentState the current state of the automation composition element + * @param newState the state to which the automation composition element is changing to + * @throws PfModelException in case of a model exception + */ + public void automationCompositionElementStateChange(ToscaConceptIdentifier automationCompositionId, + UUID automationCompositionElementId, AutomationCompositionState currentState, + AutomationCompositionOrderedState newState) throws PfModelException; + + /** + * Handle an update on a automation composition element. + * + * @param element the information on the automation composition element + * @param automationCompositionElementDefinition toscaNodeTemplate + * @throws PfModelException from Policy framework + */ + public void automationCompositionElementUpdate(ToscaConceptIdentifier automationCompositionId, + AutomationCompositionElement element, ToscaNodeTemplate automationCompositionElementDefinition) + throws PfModelException; + + /** + * Handle automationCompositionElement statistics. + * + * @param automationCompositionElementId automationCompositionElement id + * @throws PfModelException in case of a model exception + */ + public void handleStatistics(UUID automationCompositionElementId) throws PfModelException; +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java new file mode 100644 index 000000000..79f5259bf --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java @@ -0,0 +1,130 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.intermediary.api; + +import java.util.List; +import java.util.Map; +import java.util.UUID; +import org.onap.policy.clamp.models.acm.concepts.AcElementStatistics; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions; +import org.onap.policy.clamp.models.acm.concepts.Participant; +import org.onap.policy.clamp.models.acm.concepts.ParticipantState; +import org.onap.policy.clamp.models.acm.concepts.ParticipantStatistics; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; + +/** + * This interface is used by participant implementations to use the participant intermediary. + */ +public interface ParticipantIntermediaryApi { + + /** + * Register a listener for automation composition elements that are mediated by the intermediary. + * + * @param automationCompositionElementListener The automation composition element listener to register + */ + void registerAutomationCompositionElementListener( + AutomationCompositionElementListener automationCompositionElementListener); + + /** + * Get participants loops from the intermediary API. + * + * @param name the participant name, null for all + * @param version the participant version, null for all + * @return the participants + */ + List getParticipants(String name, String version); + + /** + * Get common properties of a automation composition element. + * + * @param acElementDef the automation composition element definition + * @return the common properties + */ + Map getAcElementDefinitionCommonProperties(ToscaConceptIdentifier acElementDef); + + /** + * Update the state of a participant. + * + * @param definition the definition of the participant to update the state on + * @param state the state of the participant + * @return the participant + */ + Participant updateParticipantState(ToscaConceptIdentifier definition, ParticipantState state); + + /** + * Update the statistics of a participant. + * + * @param participantStatistics the statistics of the participant + */ + void updateParticipantStatistics(ParticipantStatistics participantStatistics); + + /** + * Get automation compositions from the intermediary API. + * + * @param name the automation composition element name, null for all + * @param version the automation composition element version, null for all + * @return the automation composition elements + */ + AutomationCompositions getAutomationCompositions(String name, String version); + + /** + * Get automation composition elements from the intermediary API. + * + * @param name the automation composition element name, null for all + * @param version the automation composition element version, null for all + * @return the automation composition elements + */ + Map getAutomationCompositionElements(String name, String version); + + /** + * Get automation composition element from the intermediary API. + * + * @param id automation composition element ID + * @return the automation composition element + */ + AutomationCompositionElement getAutomationCompositionElement(UUID id); + + /** + * Update the state of a automation composition element. + * + * @param id the ID of the automation composition element to update the state on + * @param currentState the state of the automation composition element + * @param newState the state of the automation composition element + * @return AutomationCompositionElement updated automation composition element + */ + AutomationCompositionElement updateAutomationCompositionElementState(ToscaConceptIdentifier automationCompositionId, + UUID id, AutomationCompositionOrderedState currentState, AutomationCompositionState newState, + ParticipantMessageType messageType); + + /** + * Update the automation composition element statistics. + * + * @param id the ID of the automation composition element to update the state on + * @param elementStatistics the updated statistics + */ + void updateAutomationCompositionElementStatistics(UUID id, AcElementStatistics elementStatistics); +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java new file mode 100644 index 000000000..1a1f8500f --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java @@ -0,0 +1,140 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.intermediary.api.impl; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener; +import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.acm.participant.intermediary.handler.AutomationCompositionHandler; +import org.onap.policy.clamp.acm.participant.intermediary.handler.ParticipantHandler; +import org.onap.policy.clamp.models.acm.concepts.AcElementStatistics; +import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions; +import org.onap.policy.clamp.models.acm.concepts.Participant; +import org.onap.policy.clamp.models.acm.concepts.ParticipantState; +import org.onap.policy.clamp.models.acm.concepts.ParticipantStatistics; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; +import org.springframework.stereotype.Component; + +/** + * This class is api implementation used by participant intermediary. + */ +@Component +public class ParticipantIntermediaryApiImpl implements ParticipantIntermediaryApi { + + // The handler for the participant intermediary + private final ParticipantHandler participantHandler; + + // The handler for the automationComposition intermediary + private final AutomationCompositionHandler automationCompositionHandler; + + /** + * Constructor. + * + * @param participantHandler ParticipantHandler + * @param automationCompositionHandler AutomationCompositionHandler + */ + public ParticipantIntermediaryApiImpl(ParticipantHandler participantHandler, + AutomationCompositionHandler automationCompositionHandler) { + this.participantHandler = participantHandler; + this.automationCompositionHandler = automationCompositionHandler; + } + + @Override + public void registerAutomationCompositionElementListener( + AutomationCompositionElementListener automationCompositionElementListener) { + automationCompositionHandler.registerAutomationCompositionElementListener(automationCompositionElementListener); + } + + @Override + public List getParticipants(String name, String version) { + return List.of(participantHandler.getParticipant(name, version)); + } + + @Override + public Map getAcElementDefinitionCommonProperties(ToscaConceptIdentifier acElementDef) { + return participantHandler.getAcElementDefinitionCommonProperties(acElementDef); + } + + @Override + public Participant updateParticipantState(ToscaConceptIdentifier definition, ParticipantState state) { + return participantHandler.updateParticipantState(definition, state); + } + + @Override + public void updateParticipantStatistics(ParticipantStatistics participantStatistics) { + participantHandler.updateParticipantStatistics(participantStatistics); + } + + @Override + public AutomationCompositions getAutomationCompositions(String name, String version) { + return automationCompositionHandler.getAutomationCompositions(); + } + + @Override + public Map getAutomationCompositionElements(String name, String version) { + List automationCompositions = + automationCompositionHandler.getAutomationCompositions().getAutomationCompositionList(); + + for (AutomationComposition automationComposition : automationCompositions) { + if (name.equals(automationComposition.getDefinition().getName())) { + return automationComposition.getElements(); + } + } + return new LinkedHashMap<>(); + } + + @Override + public AutomationCompositionElement getAutomationCompositionElement(UUID id) { + List automationCompositions = + automationCompositionHandler.getAutomationCompositions().getAutomationCompositionList(); + + for (AutomationComposition automationComposition : automationCompositions) { + AutomationCompositionElement acElement = automationComposition.getElements().get(id); + if (acElement != null) { + return acElement; + } + } + return null; + } + + @Override + public AutomationCompositionElement updateAutomationCompositionElementState( + ToscaConceptIdentifier automationCompositionId, UUID id, AutomationCompositionOrderedState currentState, + AutomationCompositionState newState, ParticipantMessageType messageType) { + return automationCompositionHandler.updateAutomationCompositionElementState(automationCompositionId, id, + currentState, newState); + } + + @Override + public void updateAutomationCompositionElementStatistics(UUID id, AcElementStatistics elementStatistics) { + automationCompositionHandler.updateAutomationCompositionElementStatistics(id, elementStatistics); + } +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AutomationCompositionStateChangeListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AutomationCompositionStateChangeListener.java new file mode 100644 index 000000000..b9ec6a6a0 --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AutomationCompositionStateChangeListener.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.comm; + +import org.onap.policy.clamp.acm.participant.intermediary.handler.ParticipantHandler; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionStateChange; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.springframework.stereotype.Component; + +/** + * Listener for Participant State Change messages sent by CLAMP. + */ +@Component +public class AutomationCompositionStateChangeListener extends ParticipantListener { + + /** + * Constructs the object. + * + * @param participantHandler the handler for managing the state of the participant + */ + public AutomationCompositionStateChangeListener(final ParticipantHandler participantHandler) { + super(AutomationCompositionStateChange.class, participantHandler, + participantHandler::handleAutomationCompositionStateChange); + } + + @Override + public String getType() { + return ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE.name(); + } +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AutomationCompositionUpdateListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AutomationCompositionUpdateListener.java new file mode 100644 index 000000000..6c5dc127d --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AutomationCompositionUpdateListener.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.comm; + +import org.onap.policy.clamp.acm.participant.intermediary.handler.ParticipantHandler; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionUpdate; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.springframework.stereotype.Component; + +/** + * Listener for Automation Composition Update messages sent by ACM. + */ +@Component +public class AutomationCompositionUpdateListener extends ParticipantListener { + + /** + * Constructs the object. + * + * @param participantHandler the handler for managing the state of the participant + */ + public AutomationCompositionUpdateListener(final ParticipantHandler participantHandler) { + super(AutomationCompositionUpdate.class, participantHandler, + participantHandler::handleAutomationCompositionUpdate); + } + + @Override + public String getType() { + return ParticipantMessageType.AUTOMATION_COMPOSITION_UPDATE.name(); + } +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/MessageSender.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/MessageSender.java new file mode 100644 index 000000000..0810a8a8a --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/MessageSender.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.comm; + +import java.io.Closeable; +import java.util.TimerTask; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import org.onap.policy.clamp.acm.participant.intermediary.handler.ParticipantHandler; +import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantParameters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * This class sends messages from participants to CLAMP. + */ +@Component +public class MessageSender extends TimerTask implements Closeable { + private static final Logger LOGGER = LoggerFactory.getLogger(MessageSender.class); + + private final ParticipantHandler participantHandler; + private ScheduledExecutorService timerPool; + + /** + * Constructor, set the publisher. + * + * @param participantHandler the participant handler to use for gathering information + * @param parameters the parameters of the participant + */ + public MessageSender(ParticipantHandler participantHandler, ParticipantParameters parameters) { + this.participantHandler = participantHandler; + + // Kick off the timer + timerPool = makeTimerPool(); + var interval = parameters.getIntermediaryParameters().getReportingTimeIntervalMs(); + timerPool.scheduleAtFixedRate(this, interval, interval, TimeUnit.MILLISECONDS); + } + + @Override + public void run() { + LOGGER.debug("Sent heartbeat to CLAMP"); + participantHandler.sendHeartbeat(); + } + + @Override + public void close() { + timerPool.shutdown(); + } + + /** + * Makes a new timer pool. + * + * @return a new timer pool + */ + protected ScheduledExecutorService makeTimerPool() { + return Executors.newScheduledThreadPool(1); + } +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantAckListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantAckListener.java new file mode 100644 index 000000000..c5427db6b --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantAckListener.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.intermediary.comm; + +import java.util.function.Consumer; +import org.onap.policy.clamp.acm.participant.intermediary.handler.Listener; +import org.onap.policy.clamp.acm.participant.intermediary.handler.ParticipantHandler; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantAckMessage; +import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.endpoints.listeners.ScoListener; +import org.onap.policy.common.utils.coder.StandardCoderObject; + +/** + * Abstract Listener for Participant Ack messages sent by runtime. + */ +public abstract class ParticipantAckListener extends ScoListener + implements Listener { + + private final ParticipantHandler participantHandler; + private final Consumer consumer; + + /** + * Constructs the object. + * + * @param clazz class of message this handles + * @param participantHandler ParticipantHandler + * @param consumer function that handles the message + */ + protected ParticipantAckListener(Class clazz, ParticipantHandler participantHandler, Consumer consumer) { + super(clazz); + this.participantHandler = participantHandler; + this.consumer = consumer; + } + + @Override + public void onTopicEvent(CommInfrastructure infra, String topic, StandardCoderObject sco, T message) { + if (participantHandler.appliesTo(message)) { + consumer.accept(message); + } + } + + @Override + public ScoListener getScoListener() { + return this; + } +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantDeregisterAckListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantDeregisterAckListener.java new file mode 100644 index 000000000..51a2d2f9d --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantDeregisterAckListener.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.comm; + +import org.onap.policy.clamp.acm.participant.intermediary.handler.ParticipantHandler; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantDeregisterAck; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.springframework.stereotype.Component; + +/** + * Listener for Participant Deregister Ack messages sent by runtime. + * + */ +@Component +public class ParticipantDeregisterAckListener extends ParticipantAckListener { + + /** + * Constructs the object. + * + * @param participantHandler the handler for managing the state of the participant + */ + public ParticipantDeregisterAckListener(final ParticipantHandler participantHandler) { + super(ParticipantDeregisterAck.class, participantHandler, participantHandler::handleParticipantDeregisterAck); + } + + @Override + public String getType() { + return ParticipantMessageType.PARTICIPANT_DEREGISTER_ACK.name(); + } +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantListener.java new file mode 100644 index 000000000..0eaf25cca --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantListener.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.intermediary.comm; + +import java.util.function.Consumer; +import org.onap.policy.clamp.acm.participant.intermediary.handler.Listener; +import org.onap.policy.clamp.acm.participant.intermediary.handler.ParticipantHandler; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessage; +import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.endpoints.listeners.ScoListener; +import org.onap.policy.common.utils.coder.StandardCoderObject; + +/** + * Abstract Listener for Participant messages sent by CLAMP. + */ +public abstract class ParticipantListener extends ScoListener implements Listener { + + private final ParticipantHandler participantHandler; + private final Consumer consumer; + + /** + * Constructs the object. + * + * @param clazz class of message this handles + * @param participantHandler ParticipantHandler + * @param consumer function that handles the message + */ + protected ParticipantListener(Class clazz, ParticipantHandler participantHandler, Consumer consumer) { + super(clazz); + this.participantHandler = participantHandler; + this.consumer = consumer; + } + + @Override + public void onTopicEvent(CommInfrastructure infra, String topic, StandardCoderObject sco, T message) { + if (participantHandler.appliesTo(message)) { + consumer.accept(message); + } + } + + @Override + public ScoListener getScoListener() { + return this; + } +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantMessagePublisher.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantMessagePublisher.java new file mode 100644 index 000000000..67814a4e6 --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantMessagePublisher.java @@ -0,0 +1,147 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.intermediary.comm; + +import java.util.List; +import javax.ws.rs.core.Response.Status; +import org.onap.policy.clamp.acm.participant.intermediary.handler.Publisher; +import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionAck; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantDeregister; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegister; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantUpdateAck; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * This class is used to send Participant Status messages to clamp using TopicSinkClient. + * + */ +@Component +public class ParticipantMessagePublisher implements Publisher { + private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantMessagePublisher.class); + private static final String NOT_ACTIVE_TEXT = "Not Active!"; + + private boolean active = false; + private TopicSinkClient topicSinkClient; + + /** + * Constructor for instantiating ParticipantMessagePublisher. + * + * @param topicSinks the topic sinks + */ + @Override + public void active(List topicSinks) { + if (topicSinks.size() != 1) { + throw new IllegalArgumentException("Configuration unsupported, Topic sinks greater than 1"); + } + this.topicSinkClient = new TopicSinkClient(topicSinks.get(0)); + active = true; + } + + /** + * Method to send Participant Status message to clamp on demand. + * + * @param participantStatus the Participant Status + */ + public void sendParticipantStatus(final ParticipantStatus participantStatus) { + if (!active) { + throw new AutomationCompositionRuntimeException(Status.NOT_ACCEPTABLE, NOT_ACTIVE_TEXT); + } + topicSinkClient.send(participantStatus); + LOGGER.debug("Sent Participant Status message to CLAMP - {}", participantStatus); + } + + /** + * Method to send Participant Status message to clamp on demand. + * + * @param participantRegister the Participant Status + */ + public void sendParticipantRegister(final ParticipantRegister participantRegister) { + if (!active) { + throw new AutomationCompositionRuntimeException(Status.NOT_ACCEPTABLE, NOT_ACTIVE_TEXT); + } + topicSinkClient.send(participantRegister); + LOGGER.debug("Sent Participant Register message to CLAMP - {}", participantRegister); + } + + /** + * Method to send Participant Status message to clamp on demand. + * + * @param participantDeregister the Participant Status + */ + public void sendParticipantDeregister(final ParticipantDeregister participantDeregister) { + if (!active) { + throw new AutomationCompositionRuntimeException(Status.NOT_ACCEPTABLE, NOT_ACTIVE_TEXT); + } + topicSinkClient.send(participantDeregister); + LOGGER.debug("Sent Participant Deregister message to CLAMP - {}", participantDeregister); + } + + /** + * Method to send Participant Update Ack message to runtime. + * + * @param participantUpdateAck the Participant Update Ack + */ + public void sendParticipantUpdateAck(final ParticipantUpdateAck participantUpdateAck) { + if (!active) { + throw new AutomationCompositionRuntimeException(Status.NOT_ACCEPTABLE, NOT_ACTIVE_TEXT); + } + topicSinkClient.send(participantUpdateAck); + LOGGER.debug("Sent Participant Update Ack message to CLAMP - {}", participantUpdateAck); + } + + /** + * Method to send AutomationComposition Update/StateChange Ack message to runtime. + * + * @param automationCompositionAck AutomationComposition Update/StateChange Ack + */ + public void sendAutomationCompositionAck(final AutomationCompositionAck automationCompositionAck) { + if (!active) { + throw new AutomationCompositionRuntimeException(Status.NOT_ACCEPTABLE, NOT_ACTIVE_TEXT); + } + topicSinkClient.send(automationCompositionAck); + LOGGER.debug("Sent AutomationComposition Update/StateChange Ack to runtime - {}", automationCompositionAck); + } + + /** + * Method to send Participant heartbeat to clamp on demand. + * + * @param participantStatus the Participant Status + */ + public void sendHeartbeat(final ParticipantStatus participantStatus) { + if (!active) { + throw new AutomationCompositionRuntimeException(Status.NOT_ACCEPTABLE, NOT_ACTIVE_TEXT); + } + topicSinkClient.send(participantStatus); + LOGGER.debug("Sent Participant heartbeat to CLAMP - {}", participantStatus); + } + + @Override + public void stop() { + active = false; + } +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantRegisterAckListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantRegisterAckListener.java new file mode 100644 index 000000000..e29fa6f96 --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantRegisterAckListener.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.comm; + +import org.onap.policy.clamp.acm.participant.intermediary.handler.ParticipantHandler; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegisterAck; +import org.springframework.stereotype.Component; + +/** + * Listener for Participant Register Ack messages sent by runtime. + * + */ +@Component +public class ParticipantRegisterAckListener extends ParticipantAckListener { + + /** + * Constructs the object. + * + * @param participantHandler the handler for managing the state of the participant + */ + public ParticipantRegisterAckListener(final ParticipantHandler participantHandler) { + super(ParticipantRegisterAck.class, participantHandler, participantHandler::handleParticipantRegisterAck); + } + + @Override + public String getType() { + return ParticipantMessageType.PARTICIPANT_REGISTER_ACK.name(); + } +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantStatusReqListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantStatusReqListener.java new file mode 100644 index 000000000..7af3678d7 --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantStatusReqListener.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.comm; + +import org.onap.policy.clamp.acm.participant.intermediary.handler.ParticipantHandler; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatusReq; +import org.springframework.stereotype.Component; + +/** + * Listener for Participant status request messages sent by runtime to all/one participant. + */ +@Component +public class ParticipantStatusReqListener extends ParticipantListener { + + /** + * Constructs the object. + * + * @param participantHandler the handler for managing the state and health of the participant + */ + public ParticipantStatusReqListener(final ParticipantHandler participantHandler) { + super(ParticipantStatusReq.class, participantHandler, participantHandler::handleParticipantStatusReq); + } + + @Override + public String getType() { + return ParticipantMessageType.PARTICIPANT_STATUS_REQ.name(); + } +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantUpdateListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantUpdateListener.java new file mode 100644 index 000000000..19eb5fb30 --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantUpdateListener.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.comm; + +import org.onap.policy.clamp.acm.participant.intermediary.handler.ParticipantHandler; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantUpdate; +import org.springframework.stereotype.Component; + +/** + * Listener for Participant Update messages sent by runtime. + */ +@Component +public class ParticipantUpdateListener extends ParticipantListener { + + /** + * Constructs the object. + * + * @param participantHandler the handler for managing the state of the participant + */ + public ParticipantUpdateListener(final ParticipantHandler participantHandler) { + super(ParticipantUpdate.class, participantHandler, participantHandler::handleParticipantUpdate); + } + + @Override + public String getType() { + return ParticipantMessageType.PARTICIPANT_UPDATE.name(); + } +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java new file mode 100644 index 000000000..7e1fb5443 --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java @@ -0,0 +1,476 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.intermediary.handler; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; +import lombok.Getter; +import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener; +import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher; +import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantParameters; +import org.onap.policy.clamp.models.acm.concepts.AcElementStatistics; +import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementAck; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions; +import org.onap.policy.clamp.models.acm.concepts.ParticipantUpdates; +import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionAck; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionStateChange; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionUpdate; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/* + * This class is responsible for managing the state of all automation compositions in the participant. + */ +@Component +public class AutomationCompositionHandler { + private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionHandler.class); + + private final ToscaConceptIdentifier participantType; + private final ToscaConceptIdentifier participantId; + private final ParticipantMessagePublisher publisher; + + @Getter + private final Map automationCompositionMap = new LinkedHashMap<>(); + + @Getter + private final Map elementsOnThisParticipant = new LinkedHashMap<>(); + + @Getter + private List listeners = new ArrayList<>(); + + /** + * Constructor, set the participant ID and messageSender. + * + * @param parameters the parameters of the participant + * @param publisher the ParticipantMessage Publisher + */ + public AutomationCompositionHandler(ParticipantParameters parameters, ParticipantMessagePublisher publisher) { + this.participantType = parameters.getIntermediaryParameters().getParticipantType(); + this.participantId = parameters.getIntermediaryParameters().getParticipantId(); + this.publisher = publisher; + } + + public void registerAutomationCompositionElementListener(AutomationCompositionElementListener listener) { + listeners.add(listener); + } + + /** + * Handle a automation composition element state change message. + * + * @param automationCompositionId the automationComposition Id + * @param id the automationComposition UUID + * @param orderedState the current state + * @param newState the ordered state + * @return automationCompositionElement the updated automation composition element + */ + public AutomationCompositionElement updateAutomationCompositionElementState( + ToscaConceptIdentifier automationCompositionId, UUID id, AutomationCompositionOrderedState orderedState, + AutomationCompositionState newState) { + + if (id == null) { + LOGGER.warn("Cannot update Automation composition element state, id is null"); + return null; + } + + // Update states of AutomationCompositionElement in automationCompositionMap + for (var automationComposition : automationCompositionMap.values()) { + var element = automationComposition.getElements().get(id); + if (element != null) { + element.setOrderedState(orderedState); + element.setState(newState); + } + var checkOpt = automationComposition.getElements().values().stream() + .filter(acElement -> !newState.equals(acElement.getState())).findAny(); + if (checkOpt.isEmpty()) { + automationComposition.setState(newState); + automationComposition.setOrderedState(orderedState); + } + } + + // Update states of AutomationCompositionElement in elementsOnThisParticipant + var acElement = elementsOnThisParticipant.get(id); + if (acElement != null) { + var automationCompositionStateChangeAck = + new AutomationCompositionAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK); + automationCompositionStateChangeAck.setParticipantId(participantId); + automationCompositionStateChangeAck.setParticipantType(participantType); + automationCompositionStateChangeAck.setAutomationCompositionId(automationCompositionId); + acElement.setOrderedState(orderedState); + acElement.setState(newState); + automationCompositionStateChangeAck.getAutomationCompositionResultMap().put(acElement.getId(), + new AutomationCompositionElementAck(newState, true, + "Automation composition element {} state changed to {}\", id, newState)")); + LOGGER.debug("Automation composition element {} state changed to {}", id, newState); + automationCompositionStateChangeAck + .setMessage("AutomationCompositionElement state changed to {} " + newState); + automationCompositionStateChangeAck.setResult(true); + publisher.sendAutomationCompositionAck(automationCompositionStateChangeAck); + return acElement; + } + return null; + } + + /** + * Handle a automation composition element statistics. + * + * @param id automation composition element id + * @param elementStatistics automation composition element Statistics + */ + public void updateAutomationCompositionElementStatistics(UUID id, AcElementStatistics elementStatistics) { + var acElement = elementsOnThisParticipant.get(id); + if (acElement != null) { + elementStatistics.setParticipantId(participantId); + elementStatistics.setId(id); + acElement.setAcElementStatistics(elementStatistics); + } + } + + /** + * Handle a automation composition state change message. + * + * @param stateChangeMsg the state change message + * @param acElementDefinitions the list of AutomationCompositionElementDefinition + */ + public void handleAutomationCompositionStateChange(AutomationCompositionStateChange stateChangeMsg, + List acElementDefinitions) { + if (stateChangeMsg.getAutomationCompositionId() == null) { + return; + } + + var automationComposition = automationCompositionMap.get(stateChangeMsg.getAutomationCompositionId()); + + if (automationComposition == null) { + var automationCompositionAck = + new AutomationCompositionAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK); + automationCompositionAck.setParticipantId(participantId); + automationCompositionAck.setParticipantType(participantType); + automationCompositionAck.setMessage("Automation composition " + stateChangeMsg.getAutomationCompositionId() + + " does not use this participant " + participantId); + automationCompositionAck.setResult(false); + automationCompositionAck.setResponseTo(stateChangeMsg.getMessageId()); + automationCompositionAck.setAutomationCompositionId(stateChangeMsg.getAutomationCompositionId()); + publisher.sendAutomationCompositionAck(automationCompositionAck); + LOGGER.debug("Automation composition {} does not use this participant", + stateChangeMsg.getAutomationCompositionId()); + return; + } + + handleState(automationComposition, stateChangeMsg.getOrderedState(), stateChangeMsg.getStartPhase(), + acElementDefinitions); + } + + /** + * Method to handle state changes. + * + * @param automationComposition participant response + * @param orderedState automation composition ordered state + * @param startPhaseMsg startPhase from message + * @param acElementDefinitions the list of AutomationCompositionElementDefinition + */ + private void handleState(final AutomationComposition automationComposition, + AutomationCompositionOrderedState orderedState, Integer startPhaseMsg, + List acElementDefinitions) { + switch (orderedState) { + case UNINITIALISED: + handleUninitialisedState(automationComposition, orderedState, startPhaseMsg, acElementDefinitions); + break; + case PASSIVE: + handlePassiveState(automationComposition, orderedState, startPhaseMsg, acElementDefinitions); + break; + case RUNNING: + handleRunningState(automationComposition, orderedState, startPhaseMsg, acElementDefinitions); + break; + default: + LOGGER.debug("StateChange message has no state, state is null {}", + automationComposition.getDefinition()); + break; + } + } + + /** + * Handle a automation composition update message. + * + * @param updateMsg the update message + * @param acElementDefinitions the list of AutomationCompositionElementDefinition + */ + public void handleAutomationCompositionUpdate(AutomationCompositionUpdate updateMsg, + List acElementDefinitions) { + + if (!updateMsg.appliesTo(participantType, participantId)) { + return; + } + + if (0 == updateMsg.getStartPhase()) { + handleAcUpdatePhase0(updateMsg, acElementDefinitions); + } else { + handleAcUpdatePhaseN(updateMsg, acElementDefinitions); + } + } + + private void handleAcUpdatePhase0(AutomationCompositionUpdate updateMsg, + List acElementDefinitions) { + var automationComposition = automationCompositionMap.get(updateMsg.getAutomationCompositionId()); + + // TODO: Updates to existing AutomationCompositions are not supported yet (Addition/Removal of + // AutomationComposition + // elements to existing AutomationComposition has to be supported). + if (automationComposition != null) { + var automationCompositionUpdateAck = + new AutomationCompositionAck(ParticipantMessageType.AUTOMATION_COMPOSITION_UPDATE_ACK); + automationCompositionUpdateAck.setParticipantId(participantId); + automationCompositionUpdateAck.setParticipantType(participantType); + + automationCompositionUpdateAck.setMessage("Automation composition " + updateMsg.getAutomationCompositionId() + + " already defined on participant " + participantId); + automationCompositionUpdateAck.setResult(false); + automationCompositionUpdateAck.setResponseTo(updateMsg.getMessageId()); + automationCompositionUpdateAck.setAutomationCompositionId(updateMsg.getAutomationCompositionId()); + publisher.sendAutomationCompositionAck(automationCompositionUpdateAck); + return; + } + + if (updateMsg.getParticipantUpdatesList().isEmpty()) { + LOGGER.warn("No AutomationCompositionElement updates in message {}", + updateMsg.getAutomationCompositionId()); + return; + } + + var acElements = storeElementsOnThisParticipant(updateMsg.getParticipantUpdatesList()); + + var acElementMap = prepareAcElementMap(acElements); + automationComposition = new AutomationComposition(); + automationComposition.setDefinition(updateMsg.getAutomationCompositionId()); + automationComposition.setElements(acElementMap); + automationCompositionMap.put(updateMsg.getAutomationCompositionId(), automationComposition); + + handleAutomationCompositionElementUpdate(acElements, acElementDefinitions, updateMsg.getStartPhase(), + updateMsg.getAutomationCompositionId()); + } + + private void handleAcUpdatePhaseN(AutomationCompositionUpdate updateMsg, + List acElementDefinitions) { + + var acElementList = updateMsg.getParticipantUpdatesList().stream() + .flatMap(participantUpdate -> participantUpdate.getAutomationCompositionElementList().stream()) + .filter(element -> participantType.equals(element.getParticipantType())).collect(Collectors.toList()); + + handleAutomationCompositionElementUpdate(acElementList, acElementDefinitions, updateMsg.getStartPhase(), + updateMsg.getAutomationCompositionId()); + } + + private void handleAutomationCompositionElementUpdate(List acElements, + List acElementDefinitions, Integer startPhaseMsg, + ToscaConceptIdentifier automationCompositionId) { + try { + for (var element : acElements) { + var acElementNodeTemplate = getAcElementNodeTemplate(acElementDefinitions, element.getDefinition()); + if (acElementNodeTemplate != null) { + int startPhase = ParticipantUtils.findStartPhase(acElementNodeTemplate.getProperties()); + if (startPhaseMsg.equals(startPhase)) { + for (var acElementListener : listeners) { + acElementListener.automationCompositionElementUpdate(automationCompositionId, element, + acElementNodeTemplate); + } + } + } + } + } catch (PfModelException e) { + LOGGER.debug("Automation composition element update failed {}", automationCompositionId); + } + + } + + private ToscaNodeTemplate getAcElementNodeTemplate( + List acElementDefinitions, ToscaConceptIdentifier acElementDefId) { + + for (var acElementDefinition : acElementDefinitions) { + if (acElementDefId.getName().contains(acElementDefinition.getAcElementDefinitionId().getName())) { + return acElementDefinition.getAutomationCompositionElementToscaNodeTemplate(); + } + } + return null; + } + + private List storeElementsOnThisParticipant( + List participantUpdates) { + var acElementList = participantUpdates.stream() + .flatMap(participantUpdate -> participantUpdate.getAutomationCompositionElementList().stream()) + .filter(element -> participantType.equals(element.getParticipantType())).collect(Collectors.toList()); + + for (var element : acElementList) { + elementsOnThisParticipant.put(element.getId(), element); + } + return acElementList; + } + + private Map prepareAcElementMap(List acElements) { + Map acElementMap = new LinkedHashMap<>(); + for (var element : acElements) { + acElementMap.put(element.getId(), element); + } + return acElementMap; + } + + /** + * Method to handle when the new state from participant is UNINITIALISED state. + * + * @param automationComposition participant response + * @param orderedState orderedState + * @param startPhaseMsg startPhase from message + * @param acElementDefinitions the list of AutomationCompositionElementDefinition + */ + private void handleUninitialisedState(final AutomationComposition automationComposition, + final AutomationCompositionOrderedState orderedState, Integer startPhaseMsg, + List acElementDefinitions) { + handleStateChange(automationComposition, orderedState, startPhaseMsg, acElementDefinitions); + boolean isAllUninitialised = automationComposition.getElements().values().stream() + .filter(element -> !AutomationCompositionState.UNINITIALISED.equals(element.getState())).findAny() + .isEmpty(); + if (isAllUninitialised) { + automationCompositionMap.remove(automationComposition.getDefinition()); + automationComposition.getElements().values() + .forEach(element -> elementsOnThisParticipant.remove(element.getId())); + } + } + + /** + * Method to handle when the new state from participant is PASSIVE state. + * + * @param automationComposition participant response + * @param orderedState orderedState + * @param startPhaseMsg startPhase from message + * @param acElementDefinitions the list of AutomationCompositionElementDefinition + */ + private void handlePassiveState(final AutomationComposition automationComposition, + final AutomationCompositionOrderedState orderedState, Integer startPhaseMsg, + List acElementDefinitions) { + handleStateChange(automationComposition, orderedState, startPhaseMsg, acElementDefinitions); + } + + /** + * Method to handle when the new state from participant is RUNNING state. + * + * @param automationComposition participant response + * @param orderedState orderedState + * @param startPhaseMsg startPhase from message + * @param acElementDefinitions the list of AutomationCompositionElementDefinition + */ + private void handleRunningState(final AutomationComposition automationComposition, + final AutomationCompositionOrderedState orderedState, Integer startPhaseMsg, + List acElementDefinitions) { + handleStateChange(automationComposition, orderedState, startPhaseMsg, acElementDefinitions); + } + + /** + * Method to update the state of automation composition elements. + * + * @param automationComposition participant status in memory + * @param orderedState orderedState the new ordered state the participant should have + * @param startPhaseMsg startPhase from message + * @param acElementDefinitions the list of AutomationCompositionElementDefinition + */ + private void handleStateChange(AutomationComposition automationComposition, + final AutomationCompositionOrderedState orderedState, Integer startPhaseMsg, + List acElementDefinitions) { + + if (orderedState.equals(automationComposition.getOrderedState())) { + var automationCompositionAck = + new AutomationCompositionAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK); + automationCompositionAck.setParticipantId(participantId); + automationCompositionAck.setParticipantType(participantType); + automationCompositionAck.setMessage("Automation composition is already in state " + orderedState); + automationCompositionAck.setResult(false); + automationCompositionAck.setAutomationCompositionId(automationComposition.getDefinition()); + publisher.sendAutomationCompositionAck(automationCompositionAck); + return; + } + + automationComposition.getElements().values().stream() + .forEach(acElement -> automationCompositionElementStateChange(automationComposition, orderedState, + acElement, startPhaseMsg, acElementDefinitions)); + } + + private void automationCompositionElementStateChange(AutomationComposition automationComposition, + AutomationCompositionOrderedState orderedState, AutomationCompositionElement acElement, Integer startPhaseMsg, + List acElementDefinitions) { + var acElementNodeTemplate = getAcElementNodeTemplate(acElementDefinitions, acElement.getDefinition()); + if (acElementNodeTemplate != null) { + int startPhase = ParticipantUtils.findStartPhase(acElementNodeTemplate.getProperties()); + if (startPhaseMsg.equals(startPhase)) { + for (var acElementListener : listeners) { + try { + acElementListener.automationCompositionElementStateChange(automationComposition.getDefinition(), + acElement.getId(), acElement.getState(), orderedState); + } catch (PfModelException e) { + LOGGER.debug("Automation composition element update failed {}", + automationComposition.getDefinition()); + } + } + } + } + } + + /** + * Get automation compositions as a {@link ConrolLoops} class. + * + * @return the automation compositions + */ + public AutomationCompositions getAutomationCompositions() { + var automationCompositions = new AutomationCompositions(); + automationCompositions.setAutomationCompositionList(new ArrayList<>(automationCompositionMap.values())); + return automationCompositions; + } + + /** + * Get properties of a automation composition element. + * + * @param id the automation composition element id + * @return the instance properties + */ + public Map getAcElementInstanceProperties(UUID id) { + Map propertiesMap = new HashMap<>(); + for (var automationComposition : automationCompositionMap.values()) { + var element = automationComposition.getElements().get(id); + if (element != null) { + propertiesMap.putAll(element.getPropertiesMap()); + } + } + return propertiesMap; + } +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/IntermediaryActivator.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/IntermediaryActivator.java new file mode 100644 index 000000000..0144f669c --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/IntermediaryActivator.java @@ -0,0 +1,153 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.intermediary.handler; + +import java.io.Closeable; +import java.io.IOException; +import java.util.List; +import lombok.Getter; +import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantParameters; +import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.common.endpoints.event.comm.TopicSource; +import org.onap.policy.common.endpoints.listeners.MessageTypeDispatcher; +import org.onap.policy.common.utils.services.ServiceManagerContainer; +import org.springframework.context.event.ContextClosedEvent; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * This class activates the Participant Intermediary together with all its handlers. + */ +@Component +public class IntermediaryActivator extends ServiceManagerContainer implements Closeable { + + private static final String[] MSG_TYPE_NAMES = {"messageType"}; + + // Topics from which the participant receives and to which the participant sends messages + private List topicSinks; + private List topicSources; + + private ParticipantHandler participantHandler; + + @Getter + private final MessageTypeDispatcher msgDispatcher; + + /** + * Instantiate the activator for participant. + * + * @param parameters the ParticipantParameters + * @param participantHandler the ParticipantHandler + * @param publishers list of Publishers + * @param listeners list of Listeners + */ + public IntermediaryActivator(final ParticipantParameters parameters, ParticipantHandler participantHandler, + List publishers, List> listeners) { + this.participantHandler = participantHandler; + + topicSinks = TopicEndpointManager.getManager().addTopicSinks( + parameters.getIntermediaryParameters().getClampAutomationCompositionTopics().getTopicSinks()); + + topicSources = TopicEndpointManager.getManager().addTopicSources( + parameters.getIntermediaryParameters().getClampAutomationCompositionTopics().getTopicSources()); + + msgDispatcher = new MessageTypeDispatcher(MSG_TYPE_NAMES); + + // @formatter:off + addAction("Topic endpoint management", + () -> TopicEndpointManager.getManager().start(), + () -> TopicEndpointManager.getManager().shutdown()); + + publishers.forEach(publisher -> + addAction("Publisher " + publisher.getClass().getSimpleName(), + () -> publisher.active(topicSinks), + publisher::stop)); + + listeners.forEach(listener -> + addAction("Listener " + listener.getClass().getSimpleName(), + () -> msgDispatcher.register(listener.getType(), listener.getScoListener()), + () -> msgDispatcher.unregister(listener.getType()))); + + addAction("Topic Message Dispatcher", this::registerMsgDispatcher, this::unregisterMsgDispatcher); + // @formatter:on + } + + /** + * Handle ContextRefreshEvent. + * + * @param ctxRefreshedEvent ContextRefreshedEvent + */ + @EventListener + public void handleContextRefreshEvent(ContextRefreshedEvent ctxRefreshedEvent) { + if (!isAlive()) { + start(); + sendParticipantRegister(); + } + } + + /** + * Handle ContextClosedEvent. + * + * @param ctxClosedEvent ContextClosedEvent + */ + @EventListener + public void handleContextClosedEvent(ContextClosedEvent ctxClosedEvent) { + if (isAlive()) { + sendParticipantDeregister(); + stop(); + } + } + + private void sendParticipantRegister() { + participantHandler.sendParticipantRegister(); + } + + private void sendParticipantDeregister() { + participantHandler.sendParticipantDeregister(); + } + + /** + * Registers the dispatcher with the topic source(s). + */ + private void registerMsgDispatcher() { + for (final TopicSource source : topicSources) { + source.register(msgDispatcher); + } + } + + /** + * Unregisters the dispatcher from the topic source(s). + */ + private void unregisterMsgDispatcher() { + for (final TopicSource source : topicSources) { + source.unregister(msgDispatcher); + } + } + + @Override + public void close() throws IOException { + if (isAlive()) { + super.shutdown(); + } + } +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/Listener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/Listener.java new file mode 100644 index 000000000..56ed55441 --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/Listener.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.intermediary.handler; + +import org.onap.policy.common.endpoints.listeners.ScoListener; + +public interface Listener { + + /** + * Get the type of message of interest to the listener. + * + * @return type of message of interest to the listener + */ + String getType(); + + /** + * Get listener to register. + * + * @return listener to register + */ + ScoListener getScoListener(); +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java new file mode 100644 index 000000000..fa02f3dcf --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java @@ -0,0 +1,416 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.intermediary.handler; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; +import lombok.Getter; +import lombok.Setter; +import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener; +import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher; +import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantParameters; +import org.onap.policy.clamp.models.acm.concepts.AcElementStatisticsList; +import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionInfo; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionStatistics; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions; +import org.onap.policy.clamp.models.acm.concepts.Participant; +import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition; +import org.onap.policy.clamp.models.acm.concepts.ParticipantHealthStatus; +import org.onap.policy.clamp.models.acm.concepts.ParticipantState; +import org.onap.policy.clamp.models.acm.concepts.ParticipantStatistics; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionStateChange; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionUpdate; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantAckMessage; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantDeregister; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantDeregisterAck; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessage; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegister; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegisterAck; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatusReq; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantUpdate; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantUpdateAck; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * This class is responsible for managing the state of a participant. + */ +@Component +public class ParticipantHandler { + private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantHandler.class); + + @Getter + private final ToscaConceptIdentifier participantType; + + @Getter + private final ToscaConceptIdentifier participantId; + + private final AutomationCompositionHandler automationCompositionHandler; + private final ParticipantStatistics participantStatistics; + private final ParticipantMessagePublisher publisher; + + @Setter + private ParticipantState state = ParticipantState.UNKNOWN; + + @Setter + private ParticipantHealthStatus healthStatus = ParticipantHealthStatus.UNKNOWN; + + private final List acElementDefsOnThisParticipant = new ArrayList<>(); + + /** + * Constructor, set the participant ID and sender. + * + * @param parameters the parameters of the participant + * @param publisher the publisher for sending responses to messages + */ + public ParticipantHandler(ParticipantParameters parameters, ParticipantMessagePublisher publisher, + AutomationCompositionHandler automationCompositionHandler) { + this.participantType = parameters.getIntermediaryParameters().getParticipantType(); + this.participantId = parameters.getIntermediaryParameters().getParticipantId(); + this.publisher = publisher; + this.automationCompositionHandler = automationCompositionHandler; + this.participantStatistics = new ParticipantStatistics(); + this.participantStatistics.setParticipantId(participantId); + this.participantStatistics.setState(state); + this.participantStatistics.setHealthStatus(healthStatus); + this.participantStatistics.setTimeStamp(Instant.now()); + } + + /** + * Method which handles a participant health check event from clamp. + * + * @param participantStatusReqMsg participant participantStatusReq message + */ + public void handleParticipantStatusReq(final ParticipantStatusReq participantStatusReqMsg) { + var participantStatus = makeHeartbeat(true); + publisher.sendParticipantStatus(participantStatus); + } + + /** + * Update AutomationCompositionElement statistics. The automation composition elements listening will be + * notified to retrieve statistics from respective automation composition elements, and automation + * compositionelements + * data on the handler will be updated. + * + * @param automationCompositions the automation compositions + * @param acElementListener automation composition element listener + */ + private void updateAcElementStatistics(AutomationCompositions automationCompositions, + AutomationCompositionElementListener acElementListener) { + for (AutomationComposition automationComposition : automationCompositions.getAutomationCompositionList()) { + for (AutomationCompositionElement element : automationComposition.getElements().values()) { + try { + acElementListener.handleStatistics(element.getId()); + } catch (PfModelException e) { + LOGGER.debug("Getting statistics for automation composition element failed for element ID {}", + element.getId(), e); + } + } + } + } + + /** + * Handle a automation composition update message. + * + * @param updateMsg the update message + */ + public void handleAutomationCompositionUpdate(AutomationCompositionUpdate updateMsg) { + automationCompositionHandler.handleAutomationCompositionUpdate(updateMsg, acElementDefsOnThisParticipant); + } + + /** + * Handle a automation composition state change message. + * + * @param stateChangeMsg the state change message + */ + public void handleAutomationCompositionStateChange(AutomationCompositionStateChange stateChangeMsg) { + automationCompositionHandler.handleAutomationCompositionStateChange(stateChangeMsg, + acElementDefsOnThisParticipant); + } + + private void handleStateChange(ParticipantState newParticipantState, ParticipantUpdateAck response) { + if (state.equals(newParticipantState)) { + response.setResult(false); + response.setMessage("Participant already in state " + newParticipantState); + } else { + response.setResult(true); + response.setMessage("Participant state changed from " + state + " to " + newParticipantState); + state = newParticipantState; + } + } + + /** + * Method to update participant state. + * + * @param definition participant definition + * @param participantState participant state + * @return the participant + */ + public Participant updateParticipantState(ToscaConceptIdentifier definition, ParticipantState participantState) { + if (!Objects.equals(definition, participantId)) { + LOGGER.debug("No participant with this ID {}", definition.getName()); + return null; + } + + var participantUpdateAck = new ParticipantUpdateAck(); + handleStateChange(participantState, participantUpdateAck); + publisher.sendParticipantUpdateAck(participantUpdateAck); + return getParticipant(definition.getName(), definition.getVersion()); + } + + /** + * Method to update participant statistics. + * + * @param statistics participant statistics + */ + public void updateParticipantStatistics(ParticipantStatistics statistics) { + participantStatistics.setState(statistics.getState()); + participantStatistics.setHealthStatus(statistics.getHealthStatus()); + participantStatistics.setTimeStamp(statistics.getTimeStamp()); + participantStatistics.setAverageExecutionTime(statistics.getAverageExecutionTime()); + participantStatistics.setEventCount(statistics.getEventCount()); + } + + /** + * Get participants as a {@link Participant} class. + * + * @param name the participant name to get + * @param version the version of the participant to get + * @return the participant + */ + public Participant getParticipant(String name, String version) { + if (participantId.getName().equals(name)) { + var participant = new Participant(); + participant.setDefinition(participantId); + participant.setParticipantState(state); + participant.setHealthStatus(healthStatus); + return participant; + } + return null; + } + + /** + * Get common properties of a automation composition element. + * + * @param acElementDef the automation composition element definition + * @return the common properties + */ + public Map getAcElementDefinitionCommonProperties(ToscaConceptIdentifier acElementDef) { + Map commonPropertiesMap = new HashMap<>(); + acElementDefsOnThisParticipant.stream().forEach(definition -> { + if (definition.getAcElementDefinitionId().equals(acElementDef)) { + commonPropertiesMap.putAll(definition.getCommonPropertiesMap()); + } + }); + return commonPropertiesMap; + } + + /** + * Check if a participant message applies to this participant handler. + * + * @param participantMsg the message to check + * @return true if it applies, false otherwise + */ + public boolean appliesTo(ParticipantMessage participantMsg) { + return participantMsg.appliesTo(participantType, participantId); + } + + /** + * Check if a participant message applies to this participant handler. + * + * @param participantMsg the message to check + * @return true if it applies, false otherwise + */ + public boolean appliesTo(ParticipantAckMessage participantMsg) { + return participantMsg.appliesTo(participantType, participantId); + } + + /** + * Method to send ParticipantRegister message to automation composition runtime. + */ + public void sendParticipantRegister() { + var participantRegister = new ParticipantRegister(); + participantRegister.setParticipantId(participantId); + participantRegister.setParticipantType(participantType); + + publisher.sendParticipantRegister(participantRegister); + } + + /** + * Handle a participantRegister Ack message. + * + * @param participantRegisterAckMsg the participantRegisterAck message + */ + public void handleParticipantRegisterAck(ParticipantRegisterAck participantRegisterAckMsg) { + LOGGER.debug("ParticipantRegisterAck message received as responseTo {}", + participantRegisterAckMsg.getResponseTo()); + statusToPassive(); + publisher.sendParticipantStatus(makeHeartbeat(false)); + } + + private void statusToPassive() { + if (ParticipantHealthStatus.UNKNOWN.equals(this.healthStatus)) { + this.healthStatus = ParticipantHealthStatus.HEALTHY; + } + + if (ParticipantState.UNKNOWN.equals(this.state) || ParticipantState.TERMINATED.equals(this.state)) { + this.state = ParticipantState.PASSIVE; + } + + } + + /** + * Method to send ParticipantDeregister message to automation composition runtime. + */ + public void sendParticipantDeregister() { + var participantDeregister = new ParticipantDeregister(); + participantDeregister.setParticipantId(participantId); + participantDeregister.setParticipantType(participantType); + + publisher.sendParticipantDeregister(participantDeregister); + } + + /** + * Handle a participantDeregister Ack message. + * + * @param participantDeregisterAckMsg the participantDeregisterAck message + */ + public void handleParticipantDeregisterAck(ParticipantDeregisterAck participantDeregisterAckMsg) { + LOGGER.debug("ParticipantDeregisterAck message received as responseTo {}", + participantDeregisterAckMsg.getResponseTo()); + } + + /** + * Handle a ParticipantUpdate message. + * + * @param participantUpdateMsg the ParticipantUpdate message + */ + public void handleParticipantUpdate(ParticipantUpdate participantUpdateMsg) { + LOGGER.debug("ParticipantUpdate message received for participantId {}", + participantUpdateMsg.getParticipantId()); + + if (!participantUpdateMsg.getParticipantDefinitionUpdates().isEmpty()) { + statusToPassive(); + // This message is to commission the automation composition + for (ParticipantDefinition participantDefinition : participantUpdateMsg.getParticipantDefinitionUpdates()) { + if (participantDefinition.getParticipantType().equals(participantType)) { + acElementDefsOnThisParticipant + .addAll(participantDefinition.getAutomationCompositionElementDefinitionList()); + break; + } + } + } else { + // This message is to decommission the automation composition + acElementDefsOnThisParticipant.clear(); + this.state = ParticipantState.TERMINATED; + } + sendParticipantUpdateAck(participantUpdateMsg.getMessageId()); + } + + /** + * Method to send ParticipantUpdateAck message to automation composition runtime. + */ + public void sendParticipantUpdateAck(UUID messageId) { + var participantUpdateAck = new ParticipantUpdateAck(); + participantUpdateAck.setResponseTo(messageId); + participantUpdateAck.setMessage("Participant Update Ack message"); + participantUpdateAck.setResult(true); + participantUpdateAck.setParticipantId(participantId); + participantUpdateAck.setParticipantType(participantType); + participantUpdateAck.setState(state); + publisher.sendParticipantUpdateAck(participantUpdateAck); + } + + /** + * Dispatch a heartbeat for this participant. + */ + public void sendHeartbeat() { + publisher.sendHeartbeat(makeHeartbeat(false)); + } + + /** + * Method to send heartbeat to automation composition runtime. + */ + public ParticipantStatus makeHeartbeat(boolean responseToParticipantStatusReq) { + if (!responseToParticipantStatusReq) { + var automationCompositions = automationCompositionHandler.getAutomationCompositions(); + for (var acElementListener : automationCompositionHandler.getListeners()) { + updateAcElementStatistics(automationCompositions, acElementListener); + } + } + this.participantStatistics.setState(state); + this.participantStatistics.setHealthStatus(healthStatus); + this.participantStatistics.setTimeStamp(Instant.now()); + + var heartbeat = new ParticipantStatus(); + heartbeat.setParticipantId(participantId); + heartbeat.setParticipantStatistics(participantStatistics); + heartbeat.setParticipantType(participantType); + heartbeat.setHealthStatus(healthStatus); + heartbeat.setState(state); + heartbeat.setAutomationCompositionInfoList(getAutomationCompositionInfoList()); + + if (responseToParticipantStatusReq) { + ParticipantDefinition participantDefinition = new ParticipantDefinition(); + participantDefinition.setParticipantId(participantId); + participantDefinition.setParticipantType(participantType); + participantDefinition.setAutomationCompositionElementDefinitionList(acElementDefsOnThisParticipant); + heartbeat.setParticipantDefinitionUpdates(List.of(participantDefinition)); + } + + return heartbeat; + } + + private List getAutomationCompositionInfoList() { + List automationCompositionInfoList = new ArrayList<>(); + for (var entry : automationCompositionHandler.getAutomationCompositionMap().entrySet()) { + var acInfo = new AutomationCompositionInfo(); + acInfo.setAutomationCompositionId(entry.getKey()); + var acStatitistics = new AutomationCompositionStatistics(); + acStatitistics.setAutomationCompositionId(entry.getKey()); + var acElementStatisticsList = new AcElementStatisticsList(); + acElementStatisticsList.setAcElementStatistics(entry.getValue().getElements().values().stream() + .map(AutomationCompositionElement::getAcElementStatistics).filter(Objects::nonNull) + .collect(Collectors.toList())); + acStatitistics.setAcElementStatisticsList(acElementStatisticsList); + acInfo.setAutomationCompositionStatistics(acStatitistics); + acInfo.setState(entry.getValue().getState()); + automationCompositionInfoList.add(acInfo); + } + return automationCompositionInfoList; + } +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/Publisher.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/Publisher.java new file mode 100644 index 000000000..72aa645fd --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/Publisher.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.handler; + +import java.util.List; +import org.onap.policy.common.endpoints.event.comm.TopicSink; + +/** + * Publisher. + */ +public interface Publisher { + + void active(List topicSinks); + + void stop(); +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/parameters/ParticipantIntermediaryParameters.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/parameters/ParticipantIntermediaryParameters.java new file mode 100644 index 000000000..dcbfd1b2e --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/parameters/ParticipantIntermediaryParameters.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.parameters; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Positive; +import lombok.Getter; +import lombok.Setter; +import org.onap.policy.common.endpoints.parameters.TopicParameterGroup; +import org.onap.policy.common.parameters.validation.ParameterGroupConstraint; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +/** + * Class to hold all parameters needed for participant component. + */ +@Getter +@Setter +public class ParticipantIntermediaryParameters { + + // The ID and description of this participant + @NotNull + @Valid + private ToscaConceptIdentifier participantId; + + @NotBlank + private String description; + + // The participant type of this participant + @NotNull + @Valid + private ToscaConceptIdentifier participantType; + + // The time interval for periodic reporting of status to the CLAMP ACM server + @Valid + @Positive + private long reportingTimeIntervalMs; + + @NotNull + @ParameterGroupConstraint + private TopicParameterGroup clampAutomationCompositionTopics; +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/parameters/ParticipantParameters.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/parameters/ParticipantParameters.java new file mode 100644 index 000000000..ca9c56607 --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/parameters/ParticipantParameters.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.parameters; + +public interface ParticipantParameters { + + ParticipantIntermediaryParameters getIntermediaryParameters(); +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ControlLoopElementListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ControlLoopElementListener.java deleted file mode 100644 index 58378fa41..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ControlLoopElementListener.java +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.api; - -import java.util.UUID; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; - -/** - * This interface is implemented by participant implementations to receive updates on control loop elements. - */ -public interface ControlLoopElementListener { - /** - * Handle a control loop element state change. - * - * @param controlLoopElementId the ID of the control loop element - * @param currentState the current state of the control loop element - * @param newState the state to which the control loop element is changing to - * @throws PfModelException in case of a model exception - */ - public void controlLoopElementStateChange(ToscaConceptIdentifier controlLoopId, UUID controlLoopElementId, - ControlLoopState currentState, ControlLoopOrderedState newState) throws PfModelException; - - /** - * Handle an update on a control loop element. - * - * @param element the information on the control loop element - * @param controlLoopElementDefinition toscaNodeTemplate - * @throws PfModelException from Policy framework - */ - public void controlLoopElementUpdate(ToscaConceptIdentifier controlLoopId, ControlLoopElement element, - ToscaNodeTemplate controlLoopElementDefinition) throws PfModelException; - - /** - * Handle controlLoopElement statistics. - * - * @param controlLoopElementId controlLoopElement id - * @throws PfModelException in case of a model exception - */ - public void handleStatistics(UUID controlLoopElementId) throws PfModelException; -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java deleted file mode 100644 index 0cb4963ec..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java +++ /dev/null @@ -1,129 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.intermediary.api; - -import java.util.List; -import java.util.Map; -import java.util.UUID; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatistics; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; - -/** - * This interface is used by participant implementations to use the participant intermediary. - */ -public interface ParticipantIntermediaryApi { - - /** - * Register a listener for control loop elements that are mediated by the intermediary. - * - * @param controlLoopElementListener The control loop element listener to register - */ - void registerControlLoopElementListener(ControlLoopElementListener controlLoopElementListener); - - /** - * Get participants loops from the intermediary API. - * - * @param name the participant name, null for all - * @param version the participant version, null for all - * @return the participants - */ - List getParticipants(String name, String version); - - /** - * Get common properties of a controlloopelement. - * - * @param clElementDef the control loop element definition - * @return the common properties - */ - Map getClElementDefinitionCommonProperties(ToscaConceptIdentifier clElementDef); - - /** - * Update the state of a participant. - * - * @param definition the definition of the participant to update the state on - * @param state the state of the participant - * @return the participant - */ - Participant updateParticipantState(ToscaConceptIdentifier definition, ParticipantState state); - - /** - * Update the statistics of a participant. - * - * @param participantStatistics the statistics of the participant - */ - void updateParticipantStatistics(ParticipantStatistics participantStatistics); - - /** - * Get control loops from the intermediary API. - * - * @param name the control loop element name, null for all - * @param version the control loop element version, null for all - * @return the control loop elements - */ - ControlLoops getControlLoops(String name, String version); - - /** - * Get control loop elements from the intermediary API. - * - * @param name the control loop element name, null for all - * @param version the control loop element version, null for all - * @return the control loop elements - */ - Map getControlLoopElements(String name, String version); - - /** - * Get control loop element from the intermediary API. - * - * @param id control loop element ID - * @return the control loop element - */ - ControlLoopElement getControlLoopElement(UUID id); - - /** - * Update the state of a control loop element. - * - * @param id the ID of the control loop element to update the state on - * @param currentState the state of the control loop element - * @param newState the state of the control loop element - * @return ControlLoopElement updated control loop element - */ - ControlLoopElement updateControlLoopElementState(ToscaConceptIdentifier controlLoopId, - UUID id, ControlLoopOrderedState currentState, - ControlLoopState newState, ParticipantMessageType messageType); - - /** - * Update the control loop element statistics. - * - * @param id the ID of the control loop element to update the state on - * @param elementStatistics the updated statistics - */ - void updateControlLoopElementStatistics(UUID id, ClElementStatistics elementStatistics); -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java deleted file mode 100644 index bbafc4678..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java +++ /dev/null @@ -1,137 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.intermediary.api.impl; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatistics; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ControlLoopHandler; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; -import org.springframework.stereotype.Component; - -/** - * This class is api implementation used by participant intermediary. - */ -@Component -public class ParticipantIntermediaryApiImpl implements ParticipantIntermediaryApi { - - // The handler for the participant intermediary - private final ParticipantHandler participantHandler; - - // The handler for the controlLoop intermediary - private final ControlLoopHandler controlLoopHandler; - - /** - * Constructor. - * - * @param participantHandler ParticipantHandler - * @param controlLoopHandler ControlLoopHandler - */ - public ParticipantIntermediaryApiImpl(ParticipantHandler participantHandler, - ControlLoopHandler controlLoopHandler) { - this.participantHandler = participantHandler; - this.controlLoopHandler = controlLoopHandler; - } - - @Override - public void registerControlLoopElementListener(ControlLoopElementListener controlLoopElementListener) { - controlLoopHandler.registerControlLoopElementListener(controlLoopElementListener); - } - - @Override - public List getParticipants(String name, String version) { - return List.of(participantHandler.getParticipant(name, version)); - } - - @Override - public Map getClElementDefinitionCommonProperties(ToscaConceptIdentifier clElementDef) { - return participantHandler.getClElementDefinitionCommonProperties(clElementDef); - } - - @Override - public Participant updateParticipantState(ToscaConceptIdentifier definition, ParticipantState state) { - return participantHandler.updateParticipantState(definition, state); - } - - @Override - public void updateParticipantStatistics(ParticipantStatistics participantStatistics) { - participantHandler.updateParticipantStatistics(participantStatistics); - } - - @Override - public ControlLoops getControlLoops(String name, String version) { - return controlLoopHandler.getControlLoops(); - } - - @Override - public Map getControlLoopElements(String name, String version) { - List controlLoops = controlLoopHandler.getControlLoops().getControlLoopList(); - - for (ControlLoop controlLoop : controlLoops) { - if (name.equals(controlLoop.getDefinition().getName())) { - return controlLoop.getElements(); - } - } - return new LinkedHashMap<>(); - } - - @Override - public ControlLoopElement getControlLoopElement(UUID id) { - List controlLoops = controlLoopHandler.getControlLoops().getControlLoopList(); - - for (ControlLoop controlLoop : controlLoops) { - ControlLoopElement clElement = controlLoop.getElements().get(id); - if (clElement != null) { - return clElement; - } - } - return null; - } - - @Override - public ControlLoopElement updateControlLoopElementState(ToscaConceptIdentifier controlLoopId, - UUID id, ControlLoopOrderedState currentState, - ControlLoopState newState, ParticipantMessageType messageType) { - return controlLoopHandler.updateControlLoopElementState(controlLoopId, - id, currentState, newState); - } - - @Override - public void updateControlLoopElementStatistics(UUID id, ClElementStatistics elementStatistics) { - controlLoopHandler.updateControlLoopElementStatistics(id, elementStatistics); - } -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ControlLoopStateChangeListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ControlLoopStateChangeListener.java deleted file mode 100644 index d24f32f2f..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ControlLoopStateChangeListener.java +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.comm; - -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopStateChange; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler; -import org.springframework.stereotype.Component; - -/** - * Listener for Participant State Change messages sent by CLAMP. - */ -@Component -public class ControlLoopStateChangeListener extends ParticipantListener { - - /** - * Constructs the object. - * - * @param participantHandler the handler for managing the state of the participant - */ - public ControlLoopStateChangeListener(final ParticipantHandler participantHandler) { - super(ControlLoopStateChange.class, participantHandler, - participantHandler::handleControlLoopStateChange); - } - - @Override - public String getType() { - return ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE.name(); - } -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ControlLoopUpdateListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ControlLoopUpdateListener.java deleted file mode 100644 index f9dec1863..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ControlLoopUpdateListener.java +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.comm; - -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler; -import org.springframework.stereotype.Component; - -/** - * Listener for Control Loop Update messages sent by CLAMP. - */ -@Component -public class ControlLoopUpdateListener extends ParticipantListener { - - /** - * Constructs the object. - * - * @param participantHandler the handler for managing the state of the participant - */ - public ControlLoopUpdateListener(final ParticipantHandler participantHandler) { - super(ControlLoopUpdate.class, participantHandler, participantHandler::handleControlLoopUpdate); - } - - @Override - public String getType() { - return ParticipantMessageType.CONTROL_LOOP_UPDATE.name(); - } -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/MessageSender.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/MessageSender.java deleted file mode 100644 index e11c883b4..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/MessageSender.java +++ /dev/null @@ -1,78 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.comm; - -import java.io.Closeable; -import java.util.TimerTask; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -/** - * This class sends messages from participants to CLAMP. - */ -@Component -public class MessageSender extends TimerTask implements Closeable { - private static final Logger LOGGER = LoggerFactory.getLogger(MessageSender.class); - - private final ParticipantHandler participantHandler; - private ScheduledExecutorService timerPool; - - /** - * Constructor, set the publisher. - * - * @param participantHandler the participant handler to use for gathering information - * @param parameters the parameters of the participant - */ - public MessageSender(ParticipantHandler participantHandler, ParticipantParameters parameters) { - this.participantHandler = participantHandler; - - // Kick off the timer - timerPool = makeTimerPool(); - var interval = parameters.getIntermediaryParameters().getReportingTimeIntervalMs(); - timerPool.scheduleAtFixedRate(this, interval, interval, TimeUnit.MILLISECONDS); - } - - @Override - public void run() { - LOGGER.debug("Sent heartbeat to CLAMP"); - participantHandler.sendHeartbeat(); - } - - @Override - public void close() { - timerPool.shutdown(); - } - - /** - * Makes a new timer pool. - * - * @return a new timer pool - */ - protected ScheduledExecutorService makeTimerPool() { - return Executors.newScheduledThreadPool(1); - } -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantAckListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantAckListener.java deleted file mode 100644 index 95bbb2940..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantAckListener.java +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.intermediary.comm; - -import java.util.function.Consumer; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantAckMessage; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.Listener; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.listeners.ScoListener; -import org.onap.policy.common.utils.coder.StandardCoderObject; - -/** - * Abstract Listener for Participant Ack messages sent by runtime. - */ -public abstract class ParticipantAckListener extends ScoListener - implements Listener { - - private final ParticipantHandler participantHandler; - private final Consumer consumer; - - /** - * Constructs the object. - * - * @param clazz class of message this handles - * @param participantHandler ParticipantHandler - * @param consumer function that handles the message - */ - protected ParticipantAckListener(Class clazz, ParticipantHandler participantHandler, Consumer consumer) { - super(clazz); - this.participantHandler = participantHandler; - this.consumer = consumer; - } - - @Override - public void onTopicEvent(CommInfrastructure infra, String topic, StandardCoderObject sco, T message) { - if (participantHandler.appliesTo(message)) { - consumer.accept(message); - } - } - - @Override - public ScoListener getScoListener() { - return this; - } -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantDeregisterAckListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantDeregisterAckListener.java deleted file mode 100644 index 5440e005b..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantDeregisterAckListener.java +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.comm; - -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregisterAck; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler; -import org.springframework.stereotype.Component; - -/** - * Listener for Participant Deregister Ack messages sent by runtime. - * - */ -@Component -public class ParticipantDeregisterAckListener extends ParticipantAckListener { - - /** - * Constructs the object. - * - * @param participantHandler the handler for managing the state of the participant - */ - public ParticipantDeregisterAckListener(final ParticipantHandler participantHandler) { - super(ParticipantDeregisterAck.class, participantHandler, participantHandler::handleParticipantDeregisterAck); - } - - @Override - public String getType() { - return ParticipantMessageType.PARTICIPANT_DEREGISTER_ACK.name(); - } -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantListener.java deleted file mode 100644 index 5326ccddc..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantListener.java +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.intermediary.comm; - -import java.util.function.Consumer; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessage; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.Listener; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.listeners.ScoListener; -import org.onap.policy.common.utils.coder.StandardCoderObject; - -/** - * Abstract Listener for Participant messages sent by CLAMP. - */ -public abstract class ParticipantListener extends ScoListener implements Listener { - - private final ParticipantHandler participantHandler; - private final Consumer consumer; - - /** - * Constructs the object. - * - * @param clazz class of message this handles - * @param participantHandler ParticipantHandler - * @param consumer function that handles the message - */ - protected ParticipantListener(Class clazz, ParticipantHandler participantHandler, Consumer consumer) { - super(clazz); - this.participantHandler = participantHandler; - this.consumer = consumer; - } - - @Override - public void onTopicEvent(CommInfrastructure infra, String topic, StandardCoderObject sco, T message) { - if (participantHandler.appliesTo(message)) { - consumer.accept(message); - } - } - - @Override - public ScoListener getScoListener() { - return this; - } -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantMessagePublisher.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantMessagePublisher.java deleted file mode 100644 index 79d62623c..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantMessagePublisher.java +++ /dev/null @@ -1,147 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.intermediary.comm; - -import java.util.List; -import javax.ws.rs.core.Response.Status; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopAck; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregister; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegister; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatus; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdateAck; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.Publisher; -import org.onap.policy.common.endpoints.event.comm.TopicSink; -import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -/** - * This class is used to send Participant Status messages to clamp using TopicSinkClient. - * - */ -@Component -public class ParticipantMessagePublisher implements Publisher { - private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantMessagePublisher.class); - private static final String NOT_ACTIVE_TEXT = "Not Active!"; - - private boolean active = false; - private TopicSinkClient topicSinkClient; - - /** - * Constructor for instantiating ParticipantMessagePublisher. - * - * @param topicSinks the topic sinks - */ - @Override - public void active(List topicSinks) { - if (topicSinks.size() != 1) { - throw new IllegalArgumentException("Configuration unsupported, Topic sinks greater than 1"); - } - this.topicSinkClient = new TopicSinkClient(topicSinks.get(0)); - active = true; - } - - /** - * Method to send Participant Status message to clamp on demand. - * - * @param participantStatus the Participant Status - */ - public void sendParticipantStatus(final ParticipantStatus participantStatus) { - if (!active) { - throw new ControlLoopRuntimeException(Status.NOT_ACCEPTABLE, NOT_ACTIVE_TEXT); - } - topicSinkClient.send(participantStatus); - LOGGER.debug("Sent Participant Status message to CLAMP - {}", participantStatus); - } - - /** - * Method to send Participant Status message to clamp on demand. - * - * @param participantRegister the Participant Status - */ - public void sendParticipantRegister(final ParticipantRegister participantRegister) { - if (!active) { - throw new ControlLoopRuntimeException(Status.NOT_ACCEPTABLE, NOT_ACTIVE_TEXT); - } - topicSinkClient.send(participantRegister); - LOGGER.debug("Sent Participant Register message to CLAMP - {}", participantRegister); - } - - /** - * Method to send Participant Status message to clamp on demand. - * - * @param participantDeregister the Participant Status - */ - public void sendParticipantDeregister(final ParticipantDeregister participantDeregister) { - if (!active) { - throw new ControlLoopRuntimeException(Status.NOT_ACCEPTABLE, NOT_ACTIVE_TEXT); - } - topicSinkClient.send(participantDeregister); - LOGGER.debug("Sent Participant Deregister message to CLAMP - {}", participantDeregister); - } - - /** - * Method to send Participant Update Ack message to runtime. - * - * @param participantUpdateAck the Participant Update Ack - */ - public void sendParticipantUpdateAck(final ParticipantUpdateAck participantUpdateAck) { - if (!active) { - throw new ControlLoopRuntimeException(Status.NOT_ACCEPTABLE, NOT_ACTIVE_TEXT); - } - topicSinkClient.send(participantUpdateAck); - LOGGER.debug("Sent Participant Update Ack message to CLAMP - {}", participantUpdateAck); - } - - /** - * Method to send ControlLoop Update/StateChange Ack message to runtime. - * - * @param controlLoopAck ControlLoop Update/StateChange Ack - */ - public void sendControlLoopAck(final ControlLoopAck controlLoopAck) { - if (!active) { - throw new ControlLoopRuntimeException(Status.NOT_ACCEPTABLE, NOT_ACTIVE_TEXT); - } - topicSinkClient.send(controlLoopAck); - LOGGER.debug("Sent ControlLoop Update/StateChange Ack to runtime - {}", controlLoopAck); - } - - /** - * Method to send Participant heartbeat to clamp on demand. - * - * @param participantStatus the Participant Status - */ - public void sendHeartbeat(final ParticipantStatus participantStatus) { - if (!active) { - throw new ControlLoopRuntimeException(Status.NOT_ACCEPTABLE, NOT_ACTIVE_TEXT); - } - topicSinkClient.send(participantStatus); - LOGGER.debug("Sent Participant heartbeat to CLAMP - {}", participantStatus); - } - - @Override - public void stop() { - active = false; - } -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantRegisterAckListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantRegisterAckListener.java deleted file mode 100644 index 7be460815..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantRegisterAckListener.java +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.comm; - -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegisterAck; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler; -import org.springframework.stereotype.Component; - -/** - * Listener for Participant Register Ack messages sent by runtime. - * - */ -@Component -public class ParticipantRegisterAckListener extends ParticipantAckListener { - - /** - * Constructs the object. - * - * @param participantHandler the handler for managing the state of the participant - */ - public ParticipantRegisterAckListener(final ParticipantHandler participantHandler) { - super(ParticipantRegisterAck.class, participantHandler, participantHandler::handleParticipantRegisterAck); - } - - @Override - public String getType() { - return ParticipantMessageType.PARTICIPANT_REGISTER_ACK.name(); - } -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantStatusReqListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantStatusReqListener.java deleted file mode 100644 index 9e978fe75..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantStatusReqListener.java +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.comm; - -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatusReq; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler; -import org.springframework.stereotype.Component; - -/** - * Listener for Participant status request messages sent by runtime to all/one participant. - */ -@Component -public class ParticipantStatusReqListener extends ParticipantListener { - - /** - * Constructs the object. - * - * @param participantHandler the handler for managing the state and health of the participant - */ - public ParticipantStatusReqListener(final ParticipantHandler participantHandler) { - super(ParticipantStatusReq.class, participantHandler, participantHandler::handleParticipantStatusReq); - } - - @Override - public String getType() { - return ParticipantMessageType.PARTICIPANT_STATUS_REQ.name(); - } -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantUpdateListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantUpdateListener.java deleted file mode 100644 index da45501e7..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantUpdateListener.java +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.comm; - -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler; -import org.springframework.stereotype.Component; - -/** - * Listener for Participant Update messages sent by runtime. - */ -@Component -public class ParticipantUpdateListener extends ParticipantListener { - - /** - * Constructs the object. - * - * @param participantHandler the handler for managing the state of the participant - */ - public ParticipantUpdateListener(final ParticipantHandler participantHandler) { - super(ParticipantUpdate.class, participantHandler, participantHandler::handleParticipantUpdate); - } - - @Override - public String getType() { - return ParticipantMessageType.PARTICIPANT_UPDATE.name(); - } -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java deleted file mode 100644 index 5a0f4989f..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java +++ /dev/null @@ -1,454 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.intermediary.handler; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.stream.Collectors; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElementAck; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElementDefinition; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUpdates; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUtils; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopAck; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopStateChange; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener; -import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantMessagePublisher; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -/* - * This class is responsible for managing the state of all control loops in the participant. - */ -@Component -public class ControlLoopHandler { - private static final Logger LOGGER = LoggerFactory.getLogger(ControlLoopHandler.class); - - private final ToscaConceptIdentifier participantType; - private final ToscaConceptIdentifier participantId; - private final ParticipantMessagePublisher publisher; - - @Getter - private final Map controlLoopMap = new LinkedHashMap<>(); - - @Getter - private final Map elementsOnThisParticipant = new LinkedHashMap<>(); - - @Getter - private List listeners = new ArrayList<>(); - - /** - * Constructor, set the participant ID and messageSender. - * - * @param parameters the parameters of the participant - * @param publisher the ParticipantMessage Publisher - */ - public ControlLoopHandler(ParticipantParameters parameters, ParticipantMessagePublisher publisher) { - this.participantType = parameters.getIntermediaryParameters().getParticipantType(); - this.participantId = parameters.getIntermediaryParameters().getParticipantId(); - this.publisher = publisher; - } - - public void registerControlLoopElementListener(ControlLoopElementListener listener) { - listeners.add(listener); - } - - /** - * Handle a control loop element state change message. - * - * @param controlLoopId the controlLoop Id - * @param id the controlLoop UUID - * @param orderedState the current state - * @param newState the ordered state - * @return controlLoopElement the updated controlloop element - */ - public ControlLoopElement updateControlLoopElementState(ToscaConceptIdentifier controlLoopId, UUID id, - ControlLoopOrderedState orderedState, ControlLoopState newState) { - - if (id == null) { - LOGGER.warn("Cannot update Control loop element state, id is null"); - return null; - } - - // Update states of ControlLoopElement in controlLoopMap - for (var controlLoop : controlLoopMap.values()) { - var element = controlLoop.getElements().get(id); - if (element != null) { - element.setOrderedState(orderedState); - element.setState(newState); - } - var checkOpt = controlLoop.getElements().values().stream() - .filter(clElement -> !newState.equals(clElement.getState())).findAny(); - if (checkOpt.isEmpty()) { - controlLoop.setState(newState); - controlLoop.setOrderedState(orderedState); - } - } - - // Update states of ControlLoopElement in elementsOnThisParticipant - var clElement = elementsOnThisParticipant.get(id); - if (clElement != null) { - var controlLoopStateChangeAck = new ControlLoopAck(ParticipantMessageType.CONTROLLOOP_STATECHANGE_ACK); - controlLoopStateChangeAck.setParticipantId(participantId); - controlLoopStateChangeAck.setParticipantType(participantType); - controlLoopStateChangeAck.setControlLoopId(controlLoopId); - clElement.setOrderedState(orderedState); - clElement.setState(newState); - controlLoopStateChangeAck.getControlLoopResultMap().put(clElement.getId(), new ControlLoopElementAck( - newState, true, "Control loop element {} state changed to {}\", id, newState)")); - LOGGER.debug("Control loop element {} state changed to {}", id, newState); - controlLoopStateChangeAck.setMessage("ControlLoopElement state changed to {} " + newState); - controlLoopStateChangeAck.setResult(true); - publisher.sendControlLoopAck(controlLoopStateChangeAck); - return clElement; - } - return null; - } - - /** - * Handle a control loop element statistics. - * - * @param id controlloop element id - * @param elementStatistics control loop element Statistics - */ - public void updateControlLoopElementStatistics(UUID id, ClElementStatistics elementStatistics) { - var clElement = elementsOnThisParticipant.get(id); - if (clElement != null) { - elementStatistics.setParticipantId(participantId); - elementStatistics.setId(id); - clElement.setClElementStatistics(elementStatistics); - } - } - - /** - * Handle a control loop state change message. - * - * @param stateChangeMsg the state change message - * @param clElementDefinitions the list of ControlLoopElementDefinition - */ - public void handleControlLoopStateChange(ControlLoopStateChange stateChangeMsg, - List clElementDefinitions) { - if (stateChangeMsg.getControlLoopId() == null) { - return; - } - - var controlLoop = controlLoopMap.get(stateChangeMsg.getControlLoopId()); - - if (controlLoop == null) { - var controlLoopAck = new ControlLoopAck(ParticipantMessageType.CONTROLLOOP_STATECHANGE_ACK); - controlLoopAck.setParticipantId(participantId); - controlLoopAck.setParticipantType(participantType); - controlLoopAck.setMessage("Control loop " + stateChangeMsg.getControlLoopId() - + " does not use this participant " + participantId); - controlLoopAck.setResult(false); - controlLoopAck.setResponseTo(stateChangeMsg.getMessageId()); - controlLoopAck.setControlLoopId(stateChangeMsg.getControlLoopId()); - publisher.sendControlLoopAck(controlLoopAck); - LOGGER.debug("Control loop {} does not use this participant", stateChangeMsg.getControlLoopId()); - return; - } - - handleState(controlLoop, stateChangeMsg.getOrderedState(), stateChangeMsg.getStartPhase(), - clElementDefinitions); - } - - /** - * Method to handle state changes. - * - * @param controlLoop participant response - * @param orderedState controlloop ordered state - * @param startPhaseMsg startPhase from message - * @param clElementDefinitions the list of ControlLoopElementDefinition - */ - private void handleState(final ControlLoop controlLoop, ControlLoopOrderedState orderedState, Integer startPhaseMsg, - List clElementDefinitions) { - switch (orderedState) { - case UNINITIALISED: - handleUninitialisedState(controlLoop, orderedState, startPhaseMsg, clElementDefinitions); - break; - case PASSIVE: - handlePassiveState(controlLoop, orderedState, startPhaseMsg, clElementDefinitions); - break; - case RUNNING: - handleRunningState(controlLoop, orderedState, startPhaseMsg, clElementDefinitions); - break; - default: - LOGGER.debug("StateChange message has no state, state is null {}", controlLoop.getDefinition()); - break; - } - } - - /** - * Handle a control loop update message. - * - * @param updateMsg the update message - * @param clElementDefinitions the list of ControlLoopElementDefinition - */ - public void handleControlLoopUpdate(ControlLoopUpdate updateMsg, - List clElementDefinitions) { - - if (!updateMsg.appliesTo(participantType, participantId)) { - return; - } - - if (0 == updateMsg.getStartPhase()) { - handleClUpdatePhase0(updateMsg, clElementDefinitions); - } else { - handleClUpdatePhaseN(updateMsg, clElementDefinitions); - } - } - - private void handleClUpdatePhase0(ControlLoopUpdate updateMsg, - List clElementDefinitions) { - var controlLoop = controlLoopMap.get(updateMsg.getControlLoopId()); - - // TODO: Updates to existing ControlLoops are not supported yet (Addition/Removal of ControlLoop - // elements to existing ControlLoop has to be supported). - if (controlLoop != null) { - var controlLoopUpdateAck = new ControlLoopAck(ParticipantMessageType.CONTROLLOOP_UPDATE_ACK); - controlLoopUpdateAck.setParticipantId(participantId); - controlLoopUpdateAck.setParticipantType(participantType); - - controlLoopUpdateAck.setMessage("Control loop " + updateMsg.getControlLoopId() - + " already defined on participant " + participantId); - controlLoopUpdateAck.setResult(false); - controlLoopUpdateAck.setResponseTo(updateMsg.getMessageId()); - controlLoopUpdateAck.setControlLoopId(updateMsg.getControlLoopId()); - publisher.sendControlLoopAck(controlLoopUpdateAck); - return; - } - - if (updateMsg.getParticipantUpdatesList().isEmpty()) { - LOGGER.warn("No ControlLoopElement updates in message {}", updateMsg.getControlLoopId()); - return; - } - - var clElements = storeElementsOnThisParticipant(updateMsg.getParticipantUpdatesList()); - - var clElementMap = prepareClElementMap(clElements); - controlLoop = new ControlLoop(); - controlLoop.setDefinition(updateMsg.getControlLoopId()); - controlLoop.setElements(clElementMap); - controlLoopMap.put(updateMsg.getControlLoopId(), controlLoop); - - handleControlLoopElementUpdate(clElements, clElementDefinitions, updateMsg.getStartPhase(), - updateMsg.getControlLoopId()); - } - - private void handleClUpdatePhaseN(ControlLoopUpdate updateMsg, - List clElementDefinitions) { - - var clElementList = updateMsg.getParticipantUpdatesList().stream() - .flatMap(participantUpdate -> participantUpdate.getControlLoopElementList().stream()) - .filter(element -> participantType.equals(element.getParticipantType())).collect(Collectors.toList()); - - handleControlLoopElementUpdate(clElementList, clElementDefinitions, updateMsg.getStartPhase(), - updateMsg.getControlLoopId()); - } - - private void handleControlLoopElementUpdate(List clElements, - List clElementDefinitions, Integer startPhaseMsg, - ToscaConceptIdentifier controlLoopId) { - try { - for (var element : clElements) { - var clElementNodeTemplate = getClElementNodeTemplate(clElementDefinitions, element.getDefinition()); - if (clElementNodeTemplate != null) { - int startPhase = ParticipantUtils.findStartPhase(clElementNodeTemplate.getProperties()); - if (startPhaseMsg.equals(startPhase)) { - for (var clElementListener : listeners) { - clElementListener.controlLoopElementUpdate(controlLoopId, element, clElementNodeTemplate); - } - } - } - } - } catch (PfModelException e) { - LOGGER.debug("Control loop element update failed {}", controlLoopId); - } - - } - - private ToscaNodeTemplate getClElementNodeTemplate(List clElementDefinitions, - ToscaConceptIdentifier clElementDefId) { - - for (var clElementDefinition : clElementDefinitions) { - if (clElementDefId.getName().contains(clElementDefinition.getClElementDefinitionId().getName())) { - return clElementDefinition.getControlLoopElementToscaNodeTemplate(); - } - } - return null; - } - - private List storeElementsOnThisParticipant(List participantUpdates) { - var clElementList = participantUpdates.stream() - .flatMap(participantUpdate -> participantUpdate.getControlLoopElementList().stream()) - .filter(element -> participantType.equals(element.getParticipantType())).collect(Collectors.toList()); - - for (var element : clElementList) { - elementsOnThisParticipant.put(element.getId(), element); - } - return clElementList; - } - - private Map prepareClElementMap(List clElements) { - Map clElementMap = new LinkedHashMap<>(); - for (var element : clElements) { - clElementMap.put(element.getId(), element); - } - return clElementMap; - } - - /** - * Method to handle when the new state from participant is UNINITIALISED state. - * - * @param controlLoop participant response - * @param orderedState orderedState - * @param startPhaseMsg startPhase from message - * @param clElementDefinitions the list of ControlLoopElementDefinition - */ - private void handleUninitialisedState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState, - Integer startPhaseMsg, List clElementDefinitions) { - handleStateChange(controlLoop, orderedState, startPhaseMsg, clElementDefinitions); - boolean isAllUninitialised = controlLoop.getElements().values().stream() - .filter(element -> !ControlLoopState.UNINITIALISED.equals(element.getState())).findAny().isEmpty(); - if (isAllUninitialised) { - controlLoopMap.remove(controlLoop.getDefinition()); - controlLoop.getElements().values().forEach(element -> elementsOnThisParticipant.remove(element.getId())); - } - } - - /** - * Method to handle when the new state from participant is PASSIVE state. - * - * @param controlLoop participant response - * @param orderedState orderedState - * @param startPhaseMsg startPhase from message - * @param clElementDefinitions the list of ControlLoopElementDefinition - */ - private void handlePassiveState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState, - Integer startPhaseMsg, List clElementDefinitions) { - handleStateChange(controlLoop, orderedState, startPhaseMsg, clElementDefinitions); - } - - /** - * Method to handle when the new state from participant is RUNNING state. - * - * @param controlLoop participant response - * @param orderedState orderedState - * @param startPhaseMsg startPhase from message - * @param clElementDefinitions the list of ControlLoopElementDefinition - */ - private void handleRunningState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState, - Integer startPhaseMsg, List clElementDefinitions) { - handleStateChange(controlLoop, orderedState, startPhaseMsg, clElementDefinitions); - } - - /** - * Method to update the state of control loop elements. - * - * @param controlLoop participant status in memory - * @param orderedState orderedState the new ordered state the participant should have - * @param startPhaseMsg startPhase from message - * @param clElementDefinitions the list of ControlLoopElementDefinition - */ - private void handleStateChange(ControlLoop controlLoop, final ControlLoopOrderedState orderedState, - Integer startPhaseMsg, List clElementDefinitions) { - - if (orderedState.equals(controlLoop.getOrderedState())) { - var controlLoopAck = new ControlLoopAck(ParticipantMessageType.CONTROLLOOP_STATECHANGE_ACK); - controlLoopAck.setParticipantId(participantId); - controlLoopAck.setParticipantType(participantType); - controlLoopAck.setMessage("Control loop is already in state " + orderedState); - controlLoopAck.setResult(false); - controlLoopAck.setControlLoopId(controlLoop.getDefinition()); - publisher.sendControlLoopAck(controlLoopAck); - return; - } - - controlLoop.getElements().values().stream().forEach(clElement -> controlLoopElementStateChange(controlLoop, - orderedState, clElement, startPhaseMsg, clElementDefinitions)); - } - - private void controlLoopElementStateChange(ControlLoop controlLoop, ControlLoopOrderedState orderedState, - ControlLoopElement clElement, Integer startPhaseMsg, - List clElementDefinitions) { - var clElementNodeTemplate = getClElementNodeTemplate(clElementDefinitions, clElement.getDefinition()); - if (clElementNodeTemplate != null) { - int startPhase = ParticipantUtils.findStartPhase(clElementNodeTemplate.getProperties()); - if (startPhaseMsg.equals(startPhase)) { - for (var clElementListener : listeners) { - try { - clElementListener.controlLoopElementStateChange(controlLoop.getDefinition(), clElement.getId(), - clElement.getState(), orderedState); - } catch (PfModelException e) { - LOGGER.debug("Control loop element update failed {}", controlLoop.getDefinition()); - } - } - } - } - } - - /** - * Get control loops as a {@link ConrolLoops} class. - * - * @return the control loops - */ - public ControlLoops getControlLoops() { - var controlLoops = new ControlLoops(); - controlLoops.setControlLoopList(new ArrayList<>(controlLoopMap.values())); - return controlLoops; - } - - /** - * Get properties of a controlloopelement. - * - * @param id the control loop element id - * @return the instance properties - */ - public Map getClElementInstanceProperties(UUID id) { - Map propertiesMap = new HashMap<>(); - for (var controlLoop : controlLoopMap.values()) { - var element = controlLoop.getElements().get(id); - if (element != null) { - propertiesMap.putAll(element.getPropertiesMap()); - } - } - return propertiesMap; - } -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivator.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivator.java deleted file mode 100644 index e42fac46e..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivator.java +++ /dev/null @@ -1,154 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.intermediary.handler; - -import java.io.Closeable; -import java.io.IOException; -import java.util.List; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; -import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager; -import org.onap.policy.common.endpoints.event.comm.TopicSink; -import org.onap.policy.common.endpoints.event.comm.TopicSource; -import org.onap.policy.common.endpoints.listeners.MessageTypeDispatcher; -import org.onap.policy.common.utils.services.ServiceManagerContainer; -import org.springframework.context.event.ContextClosedEvent; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.context.event.EventListener; -import org.springframework.stereotype.Component; - -/** - * This class activates the Participant Intermediary together with all its handlers. - */ -@Component -public class IntermediaryActivator extends ServiceManagerContainer implements Closeable { - - private static final String[] MSG_TYPE_NAMES = {"messageType"}; - - // Topics from which the participant receives and to which the participant sends messages - private List topicSinks; - private List topicSources; - - private ParticipantHandler participantHandler; - - @Getter - private final MessageTypeDispatcher msgDispatcher; - - /** - * Instantiate the activator for participant. - * - * @param parameters the ParticipantParameters - * @param participantHandler the ParticipantHandler - * @param publishers list of Publishers - * @param listeners list of Listeners - */ - public IntermediaryActivator(final ParticipantParameters parameters, - ParticipantHandler participantHandler, List publishers, - List> listeners) { - this.participantHandler = participantHandler; - - topicSinks = TopicEndpointManager.getManager() - .addTopicSinks(parameters.getIntermediaryParameters().getClampControlLoopTopics().getTopicSinks()); - - topicSources = TopicEndpointManager.getManager() - .addTopicSources(parameters.getIntermediaryParameters().getClampControlLoopTopics().getTopicSources()); - - msgDispatcher = new MessageTypeDispatcher(MSG_TYPE_NAMES); - - // @formatter:off - addAction("Topic endpoint management", - () -> TopicEndpointManager.getManager().start(), - () -> TopicEndpointManager.getManager().shutdown()); - - publishers.forEach(publisher -> - addAction("Publisher " + publisher.getClass().getSimpleName(), - () -> publisher.active(topicSinks), - publisher::stop)); - - listeners.forEach(listener -> - addAction("Listener " + listener.getClass().getSimpleName(), - () -> msgDispatcher.register(listener.getType(), listener.getScoListener()), - () -> msgDispatcher.unregister(listener.getType()))); - - addAction("Topic Message Dispatcher", this::registerMsgDispatcher, this::unregisterMsgDispatcher); - // @formatter:on - } - - /** - * Handle ContextRefreshEvent. - * - * @param ctxRefreshedEvent ContextRefreshedEvent - */ - @EventListener - public void handleContextRefreshEvent(ContextRefreshedEvent ctxRefreshedEvent) { - if (!isAlive()) { - start(); - sendParticipantRegister(); - } - } - - /** - * Handle ContextClosedEvent. - * - * @param ctxClosedEvent ContextClosedEvent - */ - @EventListener - public void handleContextClosedEvent(ContextClosedEvent ctxClosedEvent) { - if (isAlive()) { - sendParticipantDeregister(); - stop(); - } - } - - private void sendParticipantRegister() { - participantHandler.sendParticipantRegister(); - } - - private void sendParticipantDeregister() { - participantHandler.sendParticipantDeregister(); - } - - /** - * Registers the dispatcher with the topic source(s). - */ - private void registerMsgDispatcher() { - for (final TopicSource source : topicSources) { - source.register(msgDispatcher); - } - } - - /** - * Unregisters the dispatcher from the topic source(s). - */ - private void unregisterMsgDispatcher() { - for (final TopicSource source : topicSources) { - source.unregister(msgDispatcher); - } - } - - @Override - public void close() throws IOException { - if (isAlive()) { - super.shutdown(); - } - } -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/Listener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/Listener.java deleted file mode 100644 index 19bad9a67..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/Listener.java +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.intermediary.handler; - -import org.onap.policy.common.endpoints.listeners.ScoListener; - -public interface Listener { - - /** - * Get the type of message of interest to the listener. - * - * @return type of message of interest to the listener - */ - String getType(); - - /** - * Get listener to register. - * - * @return listener to register - */ - ScoListener getScoListener(); -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandler.java deleted file mode 100644 index 89a13a84b..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandler.java +++ /dev/null @@ -1,415 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * ================================================================================ - * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.participant.intermediary.handler; - -import java.time.Instant; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.UUID; -import java.util.stream.Collectors; -import lombok.Getter; -import lombok.Setter; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatisticsList; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElementDefinition; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopInfo; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopStatistics; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantHealthStatus; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatistics; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopStateChange; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantAckMessage; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregister; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregisterAck; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessage; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegister; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegisterAck; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatus; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatusReq; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdateAck; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener; -import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantMessagePublisher; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -/** - * This class is responsible for managing the state of a participant. - */ -@Component -public class ParticipantHandler { - private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantHandler.class); - - @Getter - private final ToscaConceptIdentifier participantType; - - @Getter - private final ToscaConceptIdentifier participantId; - - private final ControlLoopHandler controlLoopHandler; - private final ParticipantStatistics participantStatistics; - private final ParticipantMessagePublisher publisher; - - @Setter - private ParticipantState state = ParticipantState.UNKNOWN; - - @Setter - private ParticipantHealthStatus healthStatus = ParticipantHealthStatus.UNKNOWN; - - private final List clElementDefsOnThisParticipant = new ArrayList<>(); - - /** - * Constructor, set the participant ID and sender. - * - * @param parameters the parameters of the participant - * @param publisher the publisher for sending responses to messages - */ - public ParticipantHandler(ParticipantParameters parameters, ParticipantMessagePublisher publisher, - ControlLoopHandler controlLoopHandler) { - this.participantType = parameters.getIntermediaryParameters().getParticipantType(); - this.participantId = parameters.getIntermediaryParameters().getParticipantId(); - this.publisher = publisher; - this.controlLoopHandler = controlLoopHandler; - this.participantStatistics = new ParticipantStatistics(); - this.participantStatistics.setParticipantId(participantId); - this.participantStatistics.setState(state); - this.participantStatistics.setHealthStatus(healthStatus); - this.participantStatistics.setTimeStamp(Instant.now()); - } - - /** - * Method which handles a participant health check event from clamp. - * - * @param participantStatusReqMsg participant participantStatusReq message - */ - public void handleParticipantStatusReq(final ParticipantStatusReq participantStatusReqMsg) { - var participantStatus = makeHeartbeat(true); - publisher.sendParticipantStatus(participantStatus); - } - - /** - * Update ControlLoopElement statistics. The control loop elements listening will be - * notified to retrieve statistics from respective controlloop elements, and controlloopelements - * data on the handler will be updated. - * - * @param controlLoops the control loops - * @param clElementListener control loop element listener - */ - private void updateClElementStatistics(ControlLoops controlLoops, ControlLoopElementListener clElementListener) { - for (ControlLoop controlLoop : controlLoops.getControlLoopList()) { - for (ControlLoopElement element : controlLoop.getElements().values()) { - try { - clElementListener.handleStatistics(element.getId()); - } catch (PfModelException e) { - LOGGER.debug("Getting statistics for Control loop element failed for element ID {}", - element.getId(), e); - } - } - } - } - - /** - * Handle a control loop update message. - * - * @param updateMsg the update message - */ - public void handleControlLoopUpdate(ControlLoopUpdate updateMsg) { - controlLoopHandler.handleControlLoopUpdate(updateMsg, clElementDefsOnThisParticipant); - } - - /** - * Handle a control loop state change message. - * - * @param stateChangeMsg the state change message - */ - public void handleControlLoopStateChange(ControlLoopStateChange stateChangeMsg) { - controlLoopHandler.handleControlLoopStateChange(stateChangeMsg, clElementDefsOnThisParticipant); - } - - private void handleStateChange(ParticipantState newParticipantState, ParticipantUpdateAck response) { - if (state.equals(newParticipantState)) { - response.setResult(false); - response.setMessage("Participant already in state " + newParticipantState); - } else { - response.setResult(true); - response.setMessage("Participant state changed from " + state + " to " + newParticipantState); - state = newParticipantState; - } - } - - /** - * Method to update participant state. - * - * @param definition participant definition - * @param participantState participant state - * @return the participant - */ - public Participant updateParticipantState(ToscaConceptIdentifier definition, ParticipantState participantState) { - if (!Objects.equals(definition, participantId)) { - LOGGER.debug("No participant with this ID {}", definition.getName()); - return null; - } - - var participantUpdateAck = new ParticipantUpdateAck(); - handleStateChange(participantState, participantUpdateAck); - publisher.sendParticipantUpdateAck(participantUpdateAck); - return getParticipant(definition.getName(), definition.getVersion()); - } - - /** - * Method to update participant statistics. - * - * @param statistics participant statistics - */ - public void updateParticipantStatistics(ParticipantStatistics statistics) { - participantStatistics.setState(statistics.getState()); - participantStatistics.setHealthStatus(statistics.getHealthStatus()); - participantStatistics.setTimeStamp(statistics.getTimeStamp()); - participantStatistics.setAverageExecutionTime(statistics.getAverageExecutionTime()); - participantStatistics.setEventCount(statistics.getEventCount()); - } - - /** - * Get participants as a {@link Participant} class. - * - * @param name the participant name to get - * @param version the version of the participant to get - * @return the participant - */ - public Participant getParticipant(String name, String version) { - if (participantId.getName().equals(name)) { - var participant = new Participant(); - participant.setDefinition(participantId); - participant.setParticipantState(state); - participant.setHealthStatus(healthStatus); - return participant; - } - return null; - } - - /** - * Get common properties of a controlloopelement. - * - * @param clElementDef the control loop element definition - * @return the common properties - */ - public Map getClElementDefinitionCommonProperties(ToscaConceptIdentifier clElementDef) { - Map commonPropertiesMap = new HashMap<>(); - clElementDefsOnThisParticipant.stream().forEach(definition -> { - if (definition.getClElementDefinitionId().equals(clElementDef)) { - commonPropertiesMap.putAll(definition.getCommonPropertiesMap()); - } - }); - return commonPropertiesMap; - } - - /** - * Check if a participant message applies to this participant handler. - * - * @param participantMsg the message to check - * @return true if it applies, false otherwise - */ - public boolean appliesTo(ParticipantMessage participantMsg) { - return participantMsg.appliesTo(participantType, participantId); - } - - /** - * Check if a participant message applies to this participant handler. - * - * @param participantMsg the message to check - * @return true if it applies, false otherwise - */ - public boolean appliesTo(ParticipantAckMessage participantMsg) { - return participantMsg.appliesTo(participantType, participantId); - } - - /** - * Method to send ParticipantRegister message to controlloop runtime. - */ - public void sendParticipantRegister() { - var participantRegister = new ParticipantRegister(); - participantRegister.setParticipantId(participantId); - participantRegister.setParticipantType(participantType); - - publisher.sendParticipantRegister(participantRegister); - } - - /** - * Handle a participantRegister Ack message. - * - * @param participantRegisterAckMsg the participantRegisterAck message - */ - public void handleParticipantRegisterAck(ParticipantRegisterAck participantRegisterAckMsg) { - LOGGER.debug("ParticipantRegisterAck message received as responseTo {}", - participantRegisterAckMsg.getResponseTo()); - statusToPassive(); - publisher.sendParticipantStatus(makeHeartbeat(false)); - } - - private void statusToPassive() { - if (ParticipantHealthStatus.UNKNOWN.equals(this.healthStatus)) { - this.healthStatus = ParticipantHealthStatus.HEALTHY; - } - - if (ParticipantState.UNKNOWN.equals(this.state) || ParticipantState.TERMINATED.equals(this.state)) { - this.state = ParticipantState.PASSIVE; - } - - } - - /** - * Method to send ParticipantDeregister message to controlloop runtime. - */ - public void sendParticipantDeregister() { - var participantDeregister = new ParticipantDeregister(); - participantDeregister.setParticipantId(participantId); - participantDeregister.setParticipantType(participantType); - - publisher.sendParticipantDeregister(participantDeregister); - } - - /** - * Handle a participantDeregister Ack message. - * - * @param participantDeregisterAckMsg the participantDeregisterAck message - */ - public void handleParticipantDeregisterAck(ParticipantDeregisterAck participantDeregisterAckMsg) { - LOGGER.debug("ParticipantDeregisterAck message received as responseTo {}", - participantDeregisterAckMsg.getResponseTo()); - } - - /** - * Handle a ParticipantUpdate message. - * - * @param participantUpdateMsg the ParticipantUpdate message - */ - public void handleParticipantUpdate(ParticipantUpdate participantUpdateMsg) { - LOGGER.debug("ParticipantUpdate message received for participantId {}", - participantUpdateMsg.getParticipantId()); - - if (!participantUpdateMsg.getParticipantDefinitionUpdates().isEmpty()) { - statusToPassive(); - // This message is to commission the controlloop - for (ParticipantDefinition participantDefinition : participantUpdateMsg.getParticipantDefinitionUpdates()) { - if (participantDefinition.getParticipantType().equals(participantType)) { - clElementDefsOnThisParticipant.addAll(participantDefinition.getControlLoopElementDefinitionList()); - break; - } - } - } else { - // This message is to decommission the controlloop - clElementDefsOnThisParticipant.clear(); - this.state = ParticipantState.TERMINATED; - } - sendParticipantUpdateAck(participantUpdateMsg.getMessageId()); - } - - /** - * Method to send ParticipantUpdateAck message to controlloop runtime. - */ - public void sendParticipantUpdateAck(UUID messageId) { - var participantUpdateAck = new ParticipantUpdateAck(); - participantUpdateAck.setResponseTo(messageId); - participantUpdateAck.setMessage("Participant Update Ack message"); - participantUpdateAck.setResult(true); - participantUpdateAck.setParticipantId(participantId); - participantUpdateAck.setParticipantType(participantType); - participantUpdateAck.setState(state); - publisher.sendParticipantUpdateAck(participantUpdateAck); - } - - /** - * Dispatch a heartbeat for this participant. - */ - public void sendHeartbeat() { - publisher.sendHeartbeat(makeHeartbeat(false)); - } - - /** - * Method to send heartbeat to controlloop runtime. - */ - public ParticipantStatus makeHeartbeat(boolean responseToParticipantStatusReq) { - if (!responseToParticipantStatusReq) { - var controlLoops = controlLoopHandler.getControlLoops(); - for (var clElementListener : controlLoopHandler.getListeners()) { - updateClElementStatistics(controlLoops, clElementListener); - } - } - this.participantStatistics.setState(state); - this.participantStatistics.setHealthStatus(healthStatus); - this.participantStatistics.setTimeStamp(Instant.now()); - - var heartbeat = new ParticipantStatus(); - heartbeat.setParticipantId(participantId); - heartbeat.setParticipantStatistics(participantStatistics); - heartbeat.setParticipantType(participantType); - heartbeat.setHealthStatus(healthStatus); - heartbeat.setState(state); - heartbeat.setControlLoopInfoList(getControlLoopInfoList()); - - if (responseToParticipantStatusReq) { - ParticipantDefinition participantDefinition = new ParticipantDefinition(); - participantDefinition.setParticipantId(participantId); - participantDefinition.setParticipantType(participantType); - participantDefinition.setControlLoopElementDefinitionList(clElementDefsOnThisParticipant); - heartbeat.setParticipantDefinitionUpdates(List.of(participantDefinition)); - } - - return heartbeat; - } - - private List getControlLoopInfoList() { - List controlLoopInfoList = new ArrayList<>(); - for (var entry : controlLoopHandler.getControlLoopMap().entrySet()) { - var clInfo = new ControlLoopInfo(); - clInfo.setControlLoopId(entry.getKey()); - var clStatitistics = new ControlLoopStatistics(); - clStatitistics.setControlLoopId(entry.getKey()); - var clElementStatisticsList = new ClElementStatisticsList(); - clElementStatisticsList - .setClElementStatistics(entry.getValue().getElements().values() - .stream() - .map(ControlLoopElement::getClElementStatistics) - .filter(Objects::nonNull) - .collect(Collectors.toList())); - clStatitistics.setClElementStatisticsList(clElementStatisticsList); - clInfo.setControlLoopStatistics(clStatitistics); - clInfo.setState(entry.getValue().getState()); - controlLoopInfoList.add(clInfo); - } - return controlLoopInfoList; - } -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/Publisher.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/Publisher.java deleted file mode 100644 index 287d7c055..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/Publisher.java +++ /dev/null @@ -1,34 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.handler; - -import java.util.List; -import org.onap.policy.common.endpoints.event.comm.TopicSink; - -/** - * Publisher. - */ -public interface Publisher { - - void active(List topicSinks); - - void stop(); -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/parameters/ParticipantIntermediaryParameters.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/parameters/ParticipantIntermediaryParameters.java deleted file mode 100644 index fdc451e6b..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/parameters/ParticipantIntermediaryParameters.java +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.parameters; - -import javax.validation.Valid; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Positive; -import lombok.Getter; -import lombok.Setter; -import org.onap.policy.common.endpoints.parameters.TopicParameterGroup; -import org.onap.policy.common.parameters.validation.ParameterGroupConstraint; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; - -/** - * Class to hold all parameters needed for participant component. - */ -@Getter -@Setter -public class ParticipantIntermediaryParameters { - - // The ID and description of this participant - @NotNull - @Valid - private ToscaConceptIdentifier participantId; - - @NotBlank - private String description; - - // The participant type of this participant - @NotNull - @Valid - private ToscaConceptIdentifier participantType; - - // The time interval for periodic reporting of status to the CLAMP control loop server - @Valid - @Positive - private long reportingTimeIntervalMs; - - @NotNull - @ParameterGroupConstraint - private TopicParameterGroup clampControlLoopTopics; -} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/parameters/ParticipantParameters.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/parameters/ParticipantParameters.java deleted file mode 100644 index c350b1b95..000000000 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/parameters/ParticipantParameters.java +++ /dev/null @@ -1,26 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.parameters; - -public interface ParticipantParameters { - - ParticipantIntermediaryParameters getIntermediaryParameters(); -} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java new file mode 100644 index 000000000..5d9675606 --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java @@ -0,0 +1,103 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.api.impl; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +import java.time.Instant; +import java.util.UUID; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener; +import org.onap.policy.clamp.acm.participant.intermediary.main.parameters.CommonTestData; +import org.onap.policy.clamp.models.acm.concepts.AcElementStatistics; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.clamp.models.acm.concepts.ParticipantHealthStatus; +import org.onap.policy.clamp.models.acm.concepts.ParticipantState; +import org.onap.policy.clamp.models.acm.concepts.ParticipantStatistics; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +class ParticipantIntermediaryApiImplTest { + + private CommonTestData commonTestData = new CommonTestData(); + private static final String ID_NAME = "org.onap.PM_CDS_Blueprint"; + private static final String ID_VERSION = "1.0.1"; + + private static final String ID_NAME_E = "org.onap.domain.pmsh.PMSHAutomationCompositionDefinition"; + private static final String ID_VERSION_E = "1.0.0"; + + private static final String ID_NAME_TYPE = "org.onap.dcae.acm.DCAEMicroserviceAutomationCompositionParticipant"; + private static final String ID_VERSION_TYPE = "2.3.4"; + + @Test + void mockParticipantIntermediaryApiImplTest() throws CoderException { + var uuid = UUID.randomUUID(); + var id = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); + var participantHandler = commonTestData.getParticipantHandlerAutomationCompositions(); + var automationComposiitonHandler = commonTestData.setTestAutomationCompositionHandler(id, uuid); + var apiImpl = new ParticipantIntermediaryApiImpl(participantHandler, automationComposiitonHandler); + var acElementListener = Mockito.mock(AutomationCompositionElementListener.class); + apiImpl.registerAutomationCompositionElementListener(acElementListener); + + assertNotNull(apiImpl.getAutomationCompositions(id.getName(), id.getVersion())); + assertThat(apiImpl.getAcElementDefinitionCommonProperties(id)).isEmpty(); + + var participantStatistics = new ParticipantStatistics(); + participantStatistics.setParticipantId(id); + participantStatistics.setTimeStamp(Instant.ofEpochMilli(123456L)); + participantStatistics.setState(ParticipantState.PASSIVE); + participantStatistics.setHealthStatus(ParticipantHealthStatus.HEALTHY); + apiImpl.updateParticipantStatistics(participantStatistics); + + var participants = apiImpl.getParticipants(id.getName(), id.getVersion()); + assertEquals(ParticipantState.UNKNOWN, participants.get(0).getParticipantState()); + + var participant = apiImpl.updateParticipantState(id, ParticipantState.TERMINATED); + assertEquals(ParticipantState.TERMINATED, participant.getParticipantState()); + + var elements = apiImpl.getAutomationCompositionElements(ID_NAME_E, ID_VERSION_E); + assertFalse(elements.containsKey(uuid)); + + var element = apiImpl.getAutomationCompositionElement(elements.keySet().iterator().next()); + var idType = new ToscaConceptIdentifier(ID_NAME_TYPE, ID_VERSION_TYPE); + assertEquals(idType, element.getParticipantType()); + + var acElementStatistics = new AcElementStatistics(); + var automationCompositionId = new ToscaConceptIdentifier("defName", "0.0.1"); + acElementStatistics.setParticipantId(automationCompositionId); + acElementStatistics.setState(AutomationCompositionState.RUNNING); + acElementStatistics.setTimeStamp(Instant.now()); + + apiImpl.updateAutomationCompositionElementStatistics(uuid, acElementStatistics); + var acElement = + apiImpl.updateAutomationCompositionElementState(id, uuid, AutomationCompositionOrderedState.UNINITIALISED, + AutomationCompositionState.PASSIVE, ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK); + assertEquals(AutomationCompositionOrderedState.UNINITIALISED, acElement.getOrderedState()); + assertEquals(uuid, acElement.getId()); + + } +} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantCommTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantCommTest.java new file mode 100644 index 000000000..26dddc9ba --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantCommTest.java @@ -0,0 +1,116 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.comm; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.onap.policy.clamp.acm.participant.intermediary.main.parameters.CommonTestData; +import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionAck; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantDeregister; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegister; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.common.utils.coder.CoderException; + +class ParticipantCommTest { + + private CommonTestData commonTestData = new CommonTestData(); + + @Test + void participantReqTest() throws CoderException { + var participantHandler = commonTestData.getParticipantHandlerAutomationCompositions(); + + var participantRegisterAckListener = new ParticipantRegisterAckListener(participantHandler); + assertEquals(ParticipantMessageType.PARTICIPANT_REGISTER_ACK.name(), participantRegisterAckListener.getType()); + + var participantStatusReqListener = new ParticipantStatusReqListener(participantHandler); + assertEquals(ParticipantMessageType.PARTICIPANT_STATUS_REQ.name(), participantStatusReqListener.getType()); + + var participantDeregisterAckListener = new ParticipantDeregisterAckListener(participantHandler); + assertEquals(ParticipantMessageType.PARTICIPANT_DEREGISTER_ACK.name(), + participantDeregisterAckListener.getType()); + + var participantUpdateListener = new ParticipantUpdateListener(participantHandler); + assertEquals(ParticipantMessageType.PARTICIPANT_UPDATE.name(), participantUpdateListener.getType()); + + var automationCompositionUpdateListener = new AutomationCompositionUpdateListener(participantHandler); + assertEquals(ParticipantMessageType.AUTOMATION_COMPOSITION_UPDATE.name(), + automationCompositionUpdateListener.getType()); + + var automationCompositionStateChangeListener = new AutomationCompositionStateChangeListener(participantHandler); + assertEquals(ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE.name(), + automationCompositionStateChangeListener.getType()); + } + + @Test + void participantMessagePublisherExceptionsTest() { + var participantMessagePublisher = new ParticipantMessagePublisher(); + + var participantStatus = Mockito.mock(ParticipantStatus.class); + assertThrows(AutomationCompositionRuntimeException.class, () -> { + participantMessagePublisher.sendParticipantStatus(participantStatus); + }); + assertThrows(AutomationCompositionRuntimeException.class, () -> { + participantMessagePublisher.sendHeartbeat(participantStatus); + }); + + var participantRegister = Mockito.mock(ParticipantRegister.class); + assertThrows(AutomationCompositionRuntimeException.class, () -> { + participantMessagePublisher.sendParticipantRegister(participantRegister); + }); + + var participantDeregister = Mockito.mock(ParticipantDeregister.class); + assertThrows(AutomationCompositionRuntimeException.class, () -> { + participantMessagePublisher.sendParticipantDeregister(participantDeregister); + }); + + var automationCompositionAck = Mockito.mock(AutomationCompositionAck.class); + assertThrows(AutomationCompositionRuntimeException.class, () -> { + participantMessagePublisher.sendAutomationCompositionAck(automationCompositionAck); + }); + + List emptyList = Collections.emptyList(); + assertThrows(IllegalArgumentException.class, () -> { + participantMessagePublisher.active(emptyList); + }); + + participantMessagePublisher.stop(); + } + + @Test + void messageSenderTest() throws CoderException { + var participantHandler = commonTestData.getParticipantHandlerAutomationCompositions(); + var participantParameters = CommonTestData.getParticipantParameters(); + var messageSender = new MessageSender(participantHandler, participantParameters); + messageSender.run(); + assertFalse(messageSender.makeTimerPool().isTerminated()); + messageSender.close(); + } + +} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java new file mode 100644 index 000000000..5585e5190 --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java @@ -0,0 +1,227 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.handler; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.Mockito.mock; + +import java.time.Instant; +import java.util.List; +import java.util.UUID; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener; +import org.onap.policy.clamp.acm.participant.intermediary.main.parameters.CommonTestData; +import org.onap.policy.clamp.models.acm.concepts.AcElementStatistics; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.clamp.models.acm.concepts.ParticipantUpdates; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionStateChange; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionUpdate; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +class AutomationCompositionHandlerTest { + + private CommonTestData commonTestData = new CommonTestData(); + + @Test + void automationCompositionHandlerTest() { + var ach = commonTestData.getMockAutomationCompositionHandler(); + assertNotNull(ach.getAutomationCompositions()); + + assertNotNull(ach.getAutomationCompositionMap()); + assertNotNull(ach.getElementsOnThisParticipant()); + + var elementId1 = UUID.randomUUID(); + var element = new AutomationCompositionElement(); + element.setId(elementId1); + element.setDefinition( + new ToscaConceptIdentifier("org.onap.policy.acm.PolicyAutomationCompositionParticipant", "1.0.1")); + + element.setOrderedState(AutomationCompositionOrderedState.PASSIVE); + + AutomationCompositionElementListener listener = mock(AutomationCompositionElementListener.class); + ach.registerAutomationCompositionElementListener(listener); + assertThat(ach.getListeners()).contains(listener); + } + + @Test + void updateNullAutomationCompositionHandlerTest() { + var id = UUID.randomUUID(); + + var ach = commonTestData.getMockAutomationCompositionHandler(); + assertNull(ach.updateAutomationCompositionElementState(null, null, + AutomationCompositionOrderedState.UNINITIALISED, AutomationCompositionState.PASSIVE)); + + assertNull(ach.updateAutomationCompositionElementState(null, id, + AutomationCompositionOrderedState.UNINITIALISED, AutomationCompositionState.PASSIVE)); + + var acElementStatistics = new AcElementStatistics(); + var automationCompositionId = new ToscaConceptIdentifier("defName", "0.0.1"); + acElementStatistics.setParticipantId(automationCompositionId); + acElementStatistics.setState(AutomationCompositionState.RUNNING); + acElementStatistics.setTimeStamp(Instant.now()); + + ach.updateAutomationCompositionElementStatistics(id, acElementStatistics); + assertNull(ach.updateAutomationCompositionElementState(automationCompositionId, id, + AutomationCompositionOrderedState.UNINITIALISED, AutomationCompositionState.PASSIVE)); + } + + @Test + void updateAutomationCompositionHandlerTest() throws CoderException { + var uuid = UUID.randomUUID(); + var id = CommonTestData.getParticipantId(); + + var ach = commonTestData.setTestAutomationCompositionHandler(id, uuid); + var key = ach.getElementsOnThisParticipant().keySet().iterator().next(); + var value = ach.getElementsOnThisParticipant().get(key); + assertEquals(AutomationCompositionState.UNINITIALISED, value.getState()); + ach.updateAutomationCompositionElementState(id, uuid, AutomationCompositionOrderedState.UNINITIALISED, + AutomationCompositionState.PASSIVE); + assertEquals(AutomationCompositionState.PASSIVE, value.getState()); + + ach.getAutomationCompositionMap().values().iterator().next().getElements().putIfAbsent(key, value); + ach.updateAutomationCompositionElementState(id, key, AutomationCompositionOrderedState.PASSIVE, + AutomationCompositionState.RUNNING); + assertEquals(AutomationCompositionState.RUNNING, value.getState()); + + var acElementStatistics = new AcElementStatistics(); + acElementStatistics.setParticipantId(id); + acElementStatistics.setState(AutomationCompositionState.RUNNING); + acElementStatistics.setTimeStamp(Instant.now()); + + assertNotEquals(uuid, value.getAcElementStatistics().getId()); + ach.updateAutomationCompositionElementStatistics(uuid, acElementStatistics); + assertEquals(uuid, value.getAcElementStatistics().getId()); + + ach.getElementsOnThisParticipant().remove(key, value); + ach.getAutomationCompositionMap().values().iterator().next().getElements().clear(); + assertNull(ach.updateAutomationCompositionElementState(id, key, AutomationCompositionOrderedState.PASSIVE, + AutomationCompositionState.RUNNING)); + + } + + @Test + void handleAutomationCompositionUpdateExceptionTest() throws CoderException { + var uuid = UUID.randomUUID(); + var id = CommonTestData.getParticipantId(); + var stateChange = getStateChange(id, uuid, AutomationCompositionOrderedState.RUNNING); + var ach = commonTestData.setTestAutomationCompositionHandler(id, uuid); + assertDoesNotThrow( + () -> ach.handleAutomationCompositionStateChange(mock(AutomationCompositionStateChange.class), List.of())); + + ach.handleAutomationCompositionStateChange(stateChange, List.of()); + var newid = new ToscaConceptIdentifier("id", "1.2.3"); + stateChange.setAutomationCompositionId(newid); + stateChange.setParticipantId(newid); + assertDoesNotThrow(() -> ach.handleAutomationCompositionStateChange(stateChange, List.of())); + + var acd = new AutomationCompositionElementDefinition(); + acd.setAcElementDefinitionId(id); + var updateMsg = new AutomationCompositionUpdate(); + updateMsg.setAutomationCompositionId(id); + updateMsg.setMessageId(uuid); + updateMsg.setParticipantId(id); + updateMsg.setStartPhase(0); + var acElementDefinitions = List.of(acd); + assertDoesNotThrow(() -> ach.handleAutomationCompositionUpdate(updateMsg, acElementDefinitions)); + updateMsg.setStartPhase(1); + assertDoesNotThrow(() -> ach.handleAutomationCompositionUpdate(updateMsg, acElementDefinitions)); + assertThat(ach.getAcElementInstanceProperties(uuid)).isEmpty(); + + ach.getAutomationCompositionMap().clear(); + updateMsg.setStartPhase(0); + assertDoesNotThrow(() -> ach.handleAutomationCompositionUpdate(updateMsg, acElementDefinitions)); + + updateMsg.setAutomationCompositionId(new ToscaConceptIdentifier("new", "0.0.1")); + updateMsg.setParticipantUpdatesList(List.of(mock(ParticipantUpdates.class))); + assertDoesNotThrow(() -> ach.handleAutomationCompositionUpdate(updateMsg, acElementDefinitions)); + + updateMsg.setStartPhase(1); + var participantUpdate = new ParticipantUpdates(); + participantUpdate.setParticipantId(id); + var element = new AutomationCompositionElement(); + element.setParticipantType(id); + element.setDefinition(id); + participantUpdate.setAutomationCompositionElementList(List.of(element)); + updateMsg.setParticipantUpdatesList(List.of(participantUpdate)); + + var acd2 = new AutomationCompositionElementDefinition(); + acd2.setAcElementDefinitionId(id); + acd2.setAutomationCompositionElementToscaNodeTemplate(mock(ToscaNodeTemplate.class)); + assertDoesNotThrow(() -> ach.handleAutomationCompositionUpdate(updateMsg, List.of(acd2))); + + } + + @Test + void automationCompositionStateChangeUninitialisedTest() throws CoderException { + var uuid = UUID.randomUUID(); + var id = CommonTestData.getParticipantId(); + + var stateChangeUninitialised = getStateChange(id, uuid, AutomationCompositionOrderedState.UNINITIALISED); + + var ach = commonTestData.setTestAutomationCompositionHandler(id, uuid); + ach.handleAutomationCompositionStateChange(stateChangeUninitialised, List.of()); + var newid = new ToscaConceptIdentifier("id", "1.2.3"); + stateChangeUninitialised.setAutomationCompositionId(newid); + stateChangeUninitialised.setParticipantId(newid); + assertDoesNotThrow(() -> ach.handleAutomationCompositionStateChange(stateChangeUninitialised, List.of())); + } + + @Test + void automationCompositionStateChangePassiveTest() throws CoderException { + var uuid = UUID.randomUUID(); + var id = CommonTestData.getParticipantId(); + + var stateChangePassive = getStateChange(id, uuid, AutomationCompositionOrderedState.PASSIVE); + + var ach = commonTestData.setTestAutomationCompositionHandler(id, uuid); + ach.handleAutomationCompositionStateChange(stateChangePassive, List.of()); + var newid = new ToscaConceptIdentifier("id", "1.2.3"); + stateChangePassive.setAutomationCompositionId(newid); + stateChangePassive.setParticipantId(newid); + assertDoesNotThrow(() -> ach.handleAutomationCompositionStateChange(stateChangePassive, List.of())); + } + + private AutomationCompositionStateChange getStateChange(ToscaConceptIdentifier id, UUID uuid, + AutomationCompositionOrderedState state) { + var stateChange = new AutomationCompositionStateChange(); + stateChange.setAutomationCompositionId(id); + stateChange.setParticipantId(id); + stateChange.setMessageId(uuid); + stateChange.setOrderedState(state); + stateChange.setCurrentState(AutomationCompositionState.UNINITIALISED); + stateChange.setTimestamp(Instant.ofEpochMilli(3000)); + return stateChange; + } + +} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/DummyParticipantParameters.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/DummyParticipantParameters.java new file mode 100644 index 000000000..b82fbed6a --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/DummyParticipantParameters.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.handler; + +import javax.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; +import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantIntermediaryParameters; +import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantParameters; + +@Getter +@Setter +public class DummyParticipantParameters implements ParticipantParameters { + + @NotNull + private ParticipantIntermediaryParameters intermediaryParameters; +} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/IntermediaryActivatorTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/IntermediaryActivatorTest.java new file mode 100644 index 000000000..9ecf59ba4 --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/IntermediaryActivatorTest.java @@ -0,0 +1,103 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.handler; + +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +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.when; + +import java.util.List; +import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantStatusReqListener; +import org.onap.policy.clamp.acm.participant.intermediary.main.parameters.CommonTestData; +import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantParameters; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatusReq; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.coder.StandardCoderObject; +import org.springframework.context.event.ContextClosedEvent; +import org.springframework.context.event.ContextRefreshedEvent; + +class IntermediaryActivatorTest { + private static final Coder CODER = new StandardCoder(); + + private static final String TOPIC_FIRST = "TOPIC1"; + private static final String TOPIC_SECOND = "TOPIC2"; + + @Test + void testStartAndStop() throws Exception { + ParticipantParameters parameters = CommonTestData.getParticipantParameters(); + + var publisherFirst = spy(mock(Publisher.class)); + var publisherSecond = spy(mock(Publisher.class)); + var publishers = List.of(publisherFirst, publisherSecond); + + var listenerFirst = spy(mock(ParticipantStatusReqListener.class)); + when(listenerFirst.getType()).thenReturn(TOPIC_FIRST); + when(listenerFirst.getScoListener()).thenReturn(listenerFirst); + + var listenerSecond = spy(mock(ParticipantStatusReqListener.class)); + when(listenerSecond.getType()).thenReturn(TOPIC_SECOND); + when(listenerSecond.getScoListener()).thenReturn(listenerSecond); + + List> listeners = List.of(listenerFirst, listenerSecond); + + ParticipantHandler handler = mock(ParticipantHandler.class); + try (var activator = new IntermediaryActivator(parameters, handler, publishers, listeners)) { + + assertFalse(activator.isAlive()); + activator.start(); + assertTrue(activator.isAlive()); + + // repeat start - should throw an exception + assertThatIllegalStateException().isThrownBy(() -> activator.start()); + assertTrue(activator.isAlive()); + verify(publisherFirst, times(1)).active(anyList()); + verify(publisherSecond, times(1)).active(anyList()); + + StandardCoderObject sco = CODER.decode("{messageType:" + TOPIC_FIRST + "}", StandardCoderObject.class); + activator.getMsgDispatcher().onTopicEvent(null, "msg", sco); + verify(listenerFirst, times(1)).onTopicEvent(any(), any(), any()); + + sco = CODER.decode("{messageType:" + TOPIC_SECOND + "}", StandardCoderObject.class); + activator.getMsgDispatcher().onTopicEvent(null, "msg", sco); + verify(listenerSecond, times(1)).onTopicEvent(any(), any(), any()); + + activator.close(); + assertFalse(activator.isAlive()); + + // repeat stop - should throw an exception + assertThatIllegalStateException().isThrownBy(() -> activator.stop()); + assertFalse(activator.isAlive()); + + assertDoesNotThrow(() -> activator.handleContextRefreshEvent(mock(ContextRefreshedEvent.class))); + assertDoesNotThrow(() -> activator.handleContextClosedEvent(mock(ContextClosedEvent.class))); + } + } +} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.java new file mode 100644 index 000000000..8e22784db --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.java @@ -0,0 +1,176 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.handler; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher; +import org.onap.policy.clamp.acm.participant.intermediary.main.parameters.CommonTestData; +import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition; +import org.onap.policy.clamp.models.acm.concepts.ParticipantHealthStatus; +import org.onap.policy.clamp.models.acm.concepts.ParticipantState; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantAckMessage; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessage; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegisterAck; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantUpdate; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +class ParticipantHandlerTest { + + private CommonTestData commonTestData = new CommonTestData(); + private static final String ID_NAME = "org.onap.PM_CDS_Blueprint"; + private static final String ID_VERSION = "1.0.1"; + + @Test + void mockParticipantHandlerTest() { + var participantHandler = commonTestData.getMockParticipantHandler(); + assertNull(participantHandler.getParticipant(null, null)); + assertEquals("org.onap.PM_CDS_Blueprint 1.0.1", participantHandler.getParticipantId().toString()); + + var id = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); + assertEquals(id, participantHandler.getParticipantId()); + assertEquals(id, participantHandler.getParticipantType()); + assertThat(participantHandler.getAcElementDefinitionCommonProperties(id)).isEmpty(); + + } + + @Test + void handleUpdateTest() { + var parameters = CommonTestData.getParticipantParameters(); + var automationCompositionHander = commonTestData.getMockAutomationCompositionHandler(); + var publisher = new ParticipantMessagePublisher(); + var emptyParticipantHandler = + new ParticipantHandler(parameters, publisher, automationCompositionHander); + var participantUpdateMsg = new ParticipantUpdate(); + + assertThatThrownBy(() -> + emptyParticipantHandler.handleParticipantUpdate(participantUpdateMsg)) + .isInstanceOf(RuntimeException.class); + + var participantHandler = commonTestData.getMockParticipantHandler(); + + var id = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); + participantUpdateMsg.setAutomationCompositionId(id); + participantUpdateMsg.setParticipantId(id); + participantUpdateMsg.setParticipantType(id); + participantUpdateMsg.setMessageId(UUID.randomUUID()); + participantUpdateMsg.setTimestamp(Instant.ofEpochMilli(3000)); + + var heartbeatF = participantHandler.makeHeartbeat(false); + assertEquals(id, heartbeatF.getParticipantId()); + assertEquals(ParticipantState.UNKNOWN, heartbeatF.getParticipantStatistics().getState()); + assertThat(heartbeatF.getAutomationCompositionInfoList()).isEmpty(); + + participantHandler.handleParticipantUpdate(participantUpdateMsg); + assertThat(participantHandler.getAcElementDefinitionCommonProperties(id)).isEmpty(); + + var heartbeatT = participantHandler.makeHeartbeat(true); + assertEquals(id, heartbeatT.getParticipantId()); + assertEquals(ParticipantState.TERMINATED, heartbeatT.getParticipantStatistics().getState()); + assertThat(heartbeatT.getParticipantDefinitionUpdates()).isNotEmpty(); + assertEquals(id, heartbeatT.getParticipantDefinitionUpdates().get(0).getParticipantId()); + + var pum = setListParticipantDefinition(participantUpdateMsg); + participantHandler.handleParticipantUpdate(pum); + var heartbeatTAfterUpdate = participantHandler.makeHeartbeat(true); + assertEquals(id, heartbeatTAfterUpdate.getParticipantId()); + assertEquals(ParticipantState.PASSIVE, heartbeatTAfterUpdate.getParticipantStatistics().getState()); + + } + + private ParticipantUpdate setListParticipantDefinition(ParticipantUpdate participantUpdateMsg) { + var id = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); + List participantDefinitionUpdates = new ArrayList<>(); + var def = new ParticipantDefinition(); + def.setParticipantId(id); + def.setParticipantType(id); + participantDefinitionUpdates.add(def); + participantUpdateMsg.setParticipantDefinitionUpdates(participantDefinitionUpdates); + return participantUpdateMsg; + } + + @Test + void handleParticipantTest() { + var participantHandler = commonTestData.getMockParticipantHandler(); + var id = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); + var p = participantHandler.getParticipant(id.getName(), id.getVersion()); + assertEquals(ParticipantState.UNKNOWN, p.getParticipantState()); + + participantHandler.updateParticipantState(id, ParticipantState.PASSIVE); + var p2 = participantHandler.getParticipant(id.getName(), id.getVersion()); + assertEquals(ParticipantState.PASSIVE, p2.getParticipantState()); + + var participantRegisterAckMsg = new ParticipantRegisterAck(); + participantRegisterAckMsg.setState(ParticipantState.TERMINATED); + participantHandler.handleParticipantRegisterAck(participantRegisterAckMsg); + assertEquals(ParticipantHealthStatus.HEALTHY, participantHandler.makeHeartbeat(false).getHealthStatus()); + + var emptyid = new ToscaConceptIdentifier("", ID_VERSION); + assertNull(participantHandler.updateParticipantState(emptyid, ParticipantState.PASSIVE)); + + var sameid = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); + var participant = participantHandler.updateParticipantState(sameid, ParticipantState.PASSIVE); + assertEquals(participant.getDefinition(), sameid); + + } + + @Test + void checkAppliesTo() { + var participantHandler = commonTestData.getMockParticipantHandler(); + var participantAckMsg = + new ParticipantAckMessage(ParticipantMessageType.AUTOMATION_COMPOSITION_UPDATE); + assertTrue(participantHandler.appliesTo(participantAckMsg)); + + var participantMsg = + new ParticipantMessage(ParticipantMessageType.PARTICIPANT_STATUS); + assertTrue(participantHandler.appliesTo(participantMsg)); + + var emptyid = new ToscaConceptIdentifier("", ID_VERSION); + participantMsg.setParticipantType(emptyid); + assertFalse(participantHandler.appliesTo(participantMsg)); + + } + + @Test + void getAutomationCompositionInfoListTest() throws CoderException { + var participantHandler = commonTestData.getParticipantHandlerAutomationCompositions(); + var id = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); + participantHandler.sendHeartbeat(); + assertEquals(id, participantHandler.makeHeartbeat(false) + .getAutomationCompositionInfoList() + .get(0) + .getAutomationCompositionId()); + + } + +} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/CommonTestData.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/CommonTestData.java new file mode 100644 index 000000000..ad54d402c --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/CommonTestData.java @@ -0,0 +1,294 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.main.parameters; + +import java.io.File; +import java.time.Instant; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.UUID; +import org.mockito.Mockito; +import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher; +import org.onap.policy.clamp.acm.participant.intermediary.handler.AutomationCompositionHandler; +import org.onap.policy.clamp.acm.participant.intermediary.handler.DummyParticipantParameters; +import org.onap.policy.clamp.acm.participant.intermediary.handler.ParticipantHandler; +import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantIntermediaryParameters; +import org.onap.policy.clamp.models.acm.concepts.AcElementStatistics; +import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantDeregisterAck; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.common.endpoints.parameters.TopicParameters; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +/** + * Class to hold/create all parameters for test cases. + */ +public class CommonTestData { + public static final String PARTICIPANT_GROUP_NAME = "AutomationCompositionParticipantGroup"; + public static final String DESCRIPTION = "Participant description"; + public static final long TIME_INTERVAL = 2000; + public static final List TOPIC_PARAMS = Arrays.asList(getTopicParams()); + public static final Coder CODER = new StandardCoder(); + private static final Object lockit = new Object(); + + /** + * Get ParticipantIntermediaryParameters. + * + * @return ParticipantIntermediaryParameters + */ + public ParticipantIntermediaryParameters getParticipantIntermediaryParameters() { + try { + return CODER.convert(getIntermediaryParametersMap(PARTICIPANT_GROUP_NAME), + ParticipantIntermediaryParameters.class); + } catch (final CoderException e) { + throw new RuntimeException("cannot create ParticipantSimulatorParameters from map", e); + } + } + + /** + * Get ParticipantParameters. + * + * @return ParticipantParameters + */ + public static DummyParticipantParameters getParticipantParameters() { + try { + return CODER.convert(getParametersMap(PARTICIPANT_GROUP_NAME), DummyParticipantParameters.class); + } catch (final CoderException e) { + throw new RuntimeException("cannot create ParticipantSimulatorParameters from map", e); + } + } + + /** + * Returns a property map for a Parameters map for test cases. + * + * @param name name of the parameters + * @return a property map suitable for constructing an object + */ + public static Map getParametersMap(final String name) { + final Map map = new TreeMap<>(); + map.put("intermediaryParameters", getIntermediaryParametersMap(name)); + return map; + } + + /** + * Returns a property map for a intermediaryParameters map for test cases. + * + * @param name name of the parameters + * @return a property map suitable for constructing an object + */ + public static Map getIntermediaryParametersMap(final String name) { + final Map map = new TreeMap<>(); + map.put("name", name); + map.put("participantId", getParticipantId()); + map.put("description", DESCRIPTION); + map.put("participantType", getParticipantId()); + map.put("reportingTimeIntervalMs", TIME_INTERVAL); + map.put("clampAutomationCompositionTopics", getTopicParametersMap(false)); + + return map; + } + + /** + * Returns a property map for a TopicParameters map for test cases. + * + * @param isEmpty boolean value to represent that object created should be empty or not + * @return a property map suitable for constructing an object + */ + public static Map getTopicParametersMap(final boolean isEmpty) { + final Map map = new TreeMap<>(); + if (!isEmpty) { + map.put("topicSources", TOPIC_PARAMS); + map.put("topicSinks", TOPIC_PARAMS); + } + return map; + } + + /** + * Returns topic parameters for test cases. + * + * @return topic parameters + */ + public static TopicParameters getTopicParams() { + final var topicParams = new TopicParameters(); + topicParams.setTopic("POLICY-ACRUNTIME-PARTICIPANT"); + topicParams.setTopicCommInfrastructure("dmaap"); + topicParams.setServers(Arrays.asList("localhost")); + return topicParams; + } + + /** + * Returns participantId for test cases. + * + * @return participant Id + */ + public static ToscaConceptIdentifier getParticipantId() { + return new ToscaConceptIdentifier("org.onap.PM_CDS_Blueprint", "1.0.1"); + } + + /** + * Returns a participantMessagePublisher for MessageSender. + * + * @return participant Message Publisher + */ + private ParticipantMessagePublisher getParticipantMessagePublisher() { + synchronized (lockit) { + var participantMessagePublisher = new ParticipantMessagePublisher(); + participantMessagePublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class))); + return participantMessagePublisher; + } + } + + /** + * Returns a mocked AutomationCompositionHandler for test cases. + * + * @return AutomationCompositionHandler + */ + public AutomationCompositionHandler getMockAutomationCompositionHandler() { + return new AutomationCompositionHandler(getParticipantParameters(), getParticipantMessagePublisher()); + } + + /** + * Returns a mocked ParticipantHandler for test cases. + * + * @return participant Handler + */ + public ParticipantHandler getMockParticipantHandler() { + var parameters = getParticipantParameters(); + var automationCompositionHandler = getMockAutomationCompositionHandler(); + var publisher = new ParticipantMessagePublisher(); + publisher.active(Collections.singletonList(Mockito.mock(TopicSink.class))); + var participantHandler = new ParticipantHandler(parameters, publisher, automationCompositionHandler); + return participantHandler; + } + + /** + * Returns a mocked ParticipantHandler for test cases. + * + * @return participant Handler + * + * @throws CoderException if there is an error with .json file. + */ + public ParticipantHandler getParticipantHandlerAutomationCompositions() throws CoderException { + var automationCompositionHandler = Mockito.mock(AutomationCompositionHandler.class); + Mockito.doReturn(getTestAutomationCompositions()).when(automationCompositionHandler) + .getAutomationCompositions(); + Mockito.doReturn(getTestAutomationCompositionMap()).when(automationCompositionHandler) + .getAutomationCompositionMap(); + var publisher = new ParticipantMessagePublisher(); + publisher.active(Collections.singletonList(Mockito.mock(TopicSink.class))); + var parameters = getParticipantParameters(); + var participantHandler = new ParticipantHandler(parameters, publisher, automationCompositionHandler); + participantHandler.sendParticipantRegister(); + participantHandler.handleParticipantStatusReq(null); + participantHandler.sendParticipantDeregister(); + var participantDeregisterAckMsg = new ParticipantDeregisterAck(); + participantDeregisterAckMsg.setResponseTo(UUID.randomUUID()); + participantHandler.handleParticipantDeregisterAck(participantDeregisterAckMsg); + return participantHandler; + } + + /** + * Returns a Map of ToscaConceptIdentifier and AutomationComposition for test cases. + * + * @return automationCompositionMap + * + * @throws CoderException if there is an error with .json file. + */ + public Map getTestAutomationCompositionMap() throws CoderException { + var automationCompositions = getTestAutomationCompositions(); + var automationComposition = automationCompositions.getAutomationCompositionList().get(1); + var id = getParticipantId(); + Map automationCompositionMap = new LinkedHashMap<>(); + automationCompositionMap.put(id, automationComposition); + return automationCompositionMap; + } + + /** + * Returns List of AutomationComposition for test cases. + * + * @return AutomationCompositions + * + * @throws CoderException if there is an error with .json file. + */ + public AutomationCompositions getTestAutomationCompositions() throws CoderException { + return new StandardCoder().decode(new File("src/test/resources/providers/TestAutomationCompositions.json"), + AutomationCompositions.class); + } + + /** + * Returns a map for a elementsOnThisParticipant for test cases. + * + * @param uuid UUID and id ToscaConceptIdentifier + * @return a map suitable for elementsOnThisParticipant + */ + public Map setAutomationCompositionElementTest(UUID uuid, + ToscaConceptIdentifier id) { + var acElement = new AutomationCompositionElement(); + acElement.setId(uuid); + acElement.setParticipantId(id); + acElement.setDefinition(id); + acElement.setOrderedState(AutomationCompositionOrderedState.UNINITIALISED); + + var acElementStatistics = new AcElementStatistics(); + acElementStatistics.setParticipantId(id); + acElementStatistics.setState(AutomationCompositionState.UNINITIALISED); + acElementStatistics.setTimeStamp(Instant.now()); + + acElement.setAcElementStatistics(acElementStatistics); + + Map elementsOnThisParticipant = new LinkedHashMap<>(); + elementsOnThisParticipant.put(uuid, acElement); + return elementsOnThisParticipant; + } + + /** + * Returns a AutomationCompositionHandler with elements on the id,uuid. + * + * @param id ToscaConceptIdentifier and uuid UUID + * @return a AutomationCompositionHander with elements + */ + public AutomationCompositionHandler setTestAutomationCompositionHandler(ToscaConceptIdentifier id, UUID uuid) + throws CoderException { + var ach = getMockAutomationCompositionHandler(); + + var key = getTestAutomationCompositionMap().keySet().iterator().next(); + var value = getTestAutomationCompositionMap().get(key); + ach.getAutomationCompositionMap().put(key, value); + + var keyElem = setAutomationCompositionElementTest(uuid, id).keySet().iterator().next(); + var valueElem = setAutomationCompositionElementTest(uuid, id).get(keyElem); + ach.getElementsOnThisParticipant().put(keyElem, valueElem); + + return ach; + } + +} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/TestParticipantIntermediaryParameters.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/TestParticipantIntermediaryParameters.java new file mode 100644 index 000000000..cc2b110f3 --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/TestParticipantIntermediaryParameters.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.onap.policy.clamp.acm.participant.intermediary.main.parameters; + +import static org.assertj.core.api.Assertions.assertThat; + +import javax.validation.Validation; +import javax.validation.ValidatorFactory; +import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantIntermediaryParameters; + +/** + * Class to perform unit test of {@link ParticipantParameterGroup}. + */ +class TestParticipantIntermediaryParameters { + private CommonTestData commonTestData = new CommonTestData(); + private ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); + + @Test + void testParticipantIntermediaryParameterGroup() { + final ParticipantIntermediaryParameters participantParameters = + commonTestData.getParticipantIntermediaryParameters(); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isEmpty(); + } + + @Test + void testParticipantIntermediaryParameterGroup_EmptyParameter() { + final ParticipantIntermediaryParameters participantParameters = + commonTestData.getParticipantIntermediaryParameters(); + participantParameters.setClampAutomationCompositionTopics(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } + + @Test + void testParticipantIntermediaryParameters_NullTopicSinks() { + final ParticipantIntermediaryParameters participantParameters = + commonTestData.getParticipantIntermediaryParameters(); + participantParameters.getClampAutomationCompositionTopics().setTopicSinks(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } + + @Test + void testParticipantIntermediaryParameters_NullTopicSources() { + final ParticipantIntermediaryParameters participantParameters = + commonTestData.getParticipantIntermediaryParameters(); + participantParameters.getClampAutomationCompositionTopics().setTopicSources(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } +} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java deleted file mode 100644 index b08e796b7..000000000 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.api.impl; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; - -import java.time.Instant; -import java.util.UUID; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantHealthStatus; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatistics; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener; -import org.onap.policy.clamp.controlloop.participant.intermediary.main.parameters.CommonTestData; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; - -class ParticipantIntermediaryApiImplTest { - - private CommonTestData commonTestData = new CommonTestData(); - private static final String ID_NAME = "org.onap.PM_CDS_Blueprint"; - private static final String ID_VERSION = "1.0.1"; - - private static final String ID_NAME_E = "org.onap.domain.pmsh.PMSHControlLoopDefinition"; - private static final String ID_VERSION_E = "1.0.0"; - - private static final String ID_NAME_TYPE = "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant"; - private static final String ID_VERSION_TYPE = "2.3.4"; - - @Test - void mockParticipantIntermediaryApiImplTest() throws CoderException { - var uuid = UUID.randomUUID(); - var id = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); - var participantHandler = commonTestData.getParticipantHandlerControlLoops(); - var controlLoopHandler = commonTestData.setTestControlLoopHandler(id, uuid); - var apiImpl = new ParticipantIntermediaryApiImpl(participantHandler, controlLoopHandler); - var clElementListener = Mockito.mock(ControlLoopElementListener.class); - apiImpl.registerControlLoopElementListener(clElementListener); - - assertNotNull(apiImpl.getControlLoops(id.getName(), id.getVersion())); - assertThat(apiImpl.getClElementDefinitionCommonProperties(id)).isEmpty(); - - var participantStatistics = new ParticipantStatistics(); - participantStatistics.setParticipantId(id); - participantStatistics.setTimeStamp(Instant.ofEpochMilli(123456L)); - participantStatistics.setState(ParticipantState.PASSIVE); - participantStatistics.setHealthStatus(ParticipantHealthStatus.HEALTHY); - apiImpl.updateParticipantStatistics(participantStatistics); - - var participants = apiImpl.getParticipants(id.getName(), id.getVersion()); - assertEquals(ParticipantState.UNKNOWN, participants.get(0).getParticipantState()); - - var participant = apiImpl.updateParticipantState(id, ParticipantState.TERMINATED); - assertEquals(ParticipantState.TERMINATED, participant.getParticipantState()); - - var elements = apiImpl.getControlLoopElements(ID_NAME_E, ID_VERSION_E); - assertFalse(elements.containsKey(uuid)); - - var element = apiImpl.getControlLoopElement(elements.keySet().iterator().next()); - var idType = new ToscaConceptIdentifier(ID_NAME_TYPE, ID_VERSION_TYPE); - assertEquals(idType, element.getParticipantType()); - - var clElementStatistics = new ClElementStatistics(); - var controlLoopId = new ToscaConceptIdentifier("defName", "0.0.1"); - clElementStatistics.setParticipantId(controlLoopId); - clElementStatistics.setControlLoopState(ControlLoopState.RUNNING); - clElementStatistics.setTimeStamp(Instant.now()); - - apiImpl.updateControlLoopElementStatistics(uuid, clElementStatistics); - var clElement = apiImpl.updateControlLoopElementState(id, uuid, ControlLoopOrderedState.UNINITIALISED, - ControlLoopState.PASSIVE, ParticipantMessageType.CONTROLLOOP_STATECHANGE_ACK); - assertEquals(ControlLoopOrderedState.UNINITIALISED, clElement.getOrderedState()); - assertEquals(uuid, clElement.getId()); - - } -} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantCommTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantCommTest.java deleted file mode 100644 index a40a41853..000000000 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantCommTest.java +++ /dev/null @@ -1,119 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.comm; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.util.Collections; -import java.util.List; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopAck; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregister; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegister; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatus; -import org.onap.policy.clamp.controlloop.participant.intermediary.main.parameters.CommonTestData; -import org.onap.policy.common.endpoints.event.comm.TopicSink; -import org.onap.policy.common.utils.coder.CoderException; - -class ParticipantCommTest { - - private CommonTestData commonTestData = new CommonTestData(); - - @Test - void participantReqTest() throws CoderException { - var participantHandler = commonTestData.getParticipantHandlerControlLoops(); - - var participantRegisterAckListener = new ParticipantRegisterAckListener(participantHandler); - assertEquals(ParticipantMessageType.PARTICIPANT_REGISTER_ACK.name(), - participantRegisterAckListener.getType()); - - var participantStatusReqListener = new ParticipantStatusReqListener(participantHandler); - assertEquals(ParticipantMessageType.PARTICIPANT_STATUS_REQ.name(), - participantStatusReqListener.getType()); - - var participantDeregisterAckListener = new ParticipantDeregisterAckListener(participantHandler); - assertEquals(ParticipantMessageType.PARTICIPANT_DEREGISTER_ACK.name(), - participantDeregisterAckListener.getType()); - - var participantUpdateListener = new ParticipantUpdateListener(participantHandler); - assertEquals(ParticipantMessageType.PARTICIPANT_UPDATE.name(), - participantUpdateListener.getType()); - - var controlLoopUpdateListener = new ControlLoopUpdateListener(participantHandler); - assertEquals(ParticipantMessageType.CONTROL_LOOP_UPDATE.name(), - controlLoopUpdateListener.getType()); - - var controlLoopStateChangeListener = new ControlLoopStateChangeListener(participantHandler); - assertEquals(ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE.name(), - controlLoopStateChangeListener.getType()); - } - - @Test - void participantMessagePublisherExceptionsTest() { - var participantMessagePublisher = new ParticipantMessagePublisher(); - - var participantStatus = Mockito.mock(ParticipantStatus.class); - assertThrows(ControlLoopRuntimeException.class, () -> { - participantMessagePublisher.sendParticipantStatus(participantStatus); - }); - assertThrows(ControlLoopRuntimeException.class, () -> { - participantMessagePublisher.sendHeartbeat(participantStatus); - }); - - var participantRegister = Mockito.mock(ParticipantRegister.class); - assertThrows(ControlLoopRuntimeException.class, () -> { - participantMessagePublisher.sendParticipantRegister(participantRegister); - }); - - var participantDeregister = Mockito.mock(ParticipantDeregister.class); - assertThrows(ControlLoopRuntimeException.class, () -> { - participantMessagePublisher.sendParticipantDeregister(participantDeregister); - }); - - var controlLoopAck = Mockito.mock(ControlLoopAck.class); - assertThrows(ControlLoopRuntimeException.class, () -> { - participantMessagePublisher.sendControlLoopAck(controlLoopAck); - }); - - List emptyList = Collections.emptyList(); - assertThrows(IllegalArgumentException.class, () -> { - participantMessagePublisher.active(emptyList); - }); - - participantMessagePublisher.stop(); - } - - @Test - void messageSenderTest() throws CoderException { - var participantHandler = commonTestData.getParticipantHandlerControlLoops(); - var participantParameters = CommonTestData.getParticipantParameters(); - var messageSender = new MessageSender(participantHandler, participantParameters); - messageSender.run(); - assertFalse(messageSender.makeTimerPool().isTerminated()); - messageSender.close(); - } - -} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandlerTest.java deleted file mode 100644 index 43b43e3bf..000000000 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandlerTest.java +++ /dev/null @@ -1,226 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.handler; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.mockito.Mockito.mock; - -import java.time.Instant; -import java.util.List; -import java.util.UUID; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElementDefinition; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUpdates; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopStateChange; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener; -import org.onap.policy.clamp.controlloop.participant.intermediary.main.parameters.CommonTestData; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; -import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@ExtendWith(SpringExtension.class) -class ControlLoopHandlerTest { - - private CommonTestData commonTestData = new CommonTestData(); - - @Test - void controlLoopHandlerTest() { - var clh = commonTestData.getMockControlLoopHandler(); - assertNotNull(clh.getControlLoops()); - - assertNotNull(clh.getControlLoopMap()); - assertNotNull(clh.getElementsOnThisParticipant()); - - var elementId1 = UUID.randomUUID(); - var element = new ControlLoopElement(); - element.setId(elementId1); - element.setDefinition(new ToscaConceptIdentifier( - "org.onap.policy.controlloop.PolicyControlLoopParticipant", "1.0.1")); - - element.setOrderedState(ControlLoopOrderedState.PASSIVE); - - ControlLoopElementListener listener = mock(ControlLoopElementListener.class); - clh.registerControlLoopElementListener(listener); - assertThat(clh.getListeners()).contains(listener); - } - - @Test - void updateNullControlLoopHandlerTest() { - var id = UUID.randomUUID(); - - var clh = commonTestData.getMockControlLoopHandler(); - assertNull(clh.updateControlLoopElementState(null, null, ControlLoopOrderedState.UNINITIALISED, - ControlLoopState.PASSIVE)); - - assertNull(clh.updateControlLoopElementState(null, id, ControlLoopOrderedState.UNINITIALISED, - ControlLoopState.PASSIVE)); - - var clElementStatistics = new ClElementStatistics(); - var controlLoopId = new ToscaConceptIdentifier("defName", "0.0.1"); - clElementStatistics.setParticipantId(controlLoopId); - clElementStatistics.setControlLoopState(ControlLoopState.RUNNING); - clElementStatistics.setTimeStamp(Instant.now()); - - clh.updateControlLoopElementStatistics(id, clElementStatistics); - assertNull(clh.updateControlLoopElementState(controlLoopId, id, ControlLoopOrderedState.UNINITIALISED, - ControlLoopState.PASSIVE)); - } - - @Test - void updateControlLoopHandlerTest() throws CoderException { - var uuid = UUID.randomUUID(); - var id = CommonTestData.getParticipantId(); - - var clh = commonTestData.setTestControlLoopHandler(id, uuid); - var key = clh.getElementsOnThisParticipant().keySet().iterator().next(); - var value = clh.getElementsOnThisParticipant().get(key); - assertEquals(ControlLoopState.UNINITIALISED, value.getState()); - clh.updateControlLoopElementState(id, uuid, ControlLoopOrderedState.UNINITIALISED, - ControlLoopState.PASSIVE); - assertEquals(ControlLoopState.PASSIVE, value.getState()); - - clh.getControlLoopMap().values().iterator().next().getElements().putIfAbsent(key, value); - clh.updateControlLoopElementState(id, key, ControlLoopOrderedState.PASSIVE, - ControlLoopState.RUNNING); - assertEquals(ControlLoopState.RUNNING, value.getState()); - - var clElementStatistics = new ClElementStatistics(); - clElementStatistics.setParticipantId(id); - clElementStatistics.setControlLoopState(ControlLoopState.RUNNING); - clElementStatistics.setTimeStamp(Instant.now()); - - assertNotEquals(uuid, value.getClElementStatistics().getId()); - clh.updateControlLoopElementStatistics(uuid, clElementStatistics); - assertEquals(uuid, value.getClElementStatistics().getId()); - - clh.getElementsOnThisParticipant().remove(key, value); - clh.getControlLoopMap().values().iterator().next().getElements().clear(); - assertNull(clh.updateControlLoopElementState(id, key, ControlLoopOrderedState.PASSIVE, - ControlLoopState.RUNNING)); - - } - - @Test - void handleControlLoopUpdateExceptionTest() throws CoderException { - var uuid = UUID.randomUUID(); - var id = CommonTestData.getParticipantId(); - var stateChange = getStateChange(id, uuid, ControlLoopOrderedState.RUNNING); - var clh = commonTestData.setTestControlLoopHandler(id, uuid); - assertDoesNotThrow(() -> clh.handleControlLoopStateChange(mock(ControlLoopStateChange.class), List.of())); - - clh.handleControlLoopStateChange(stateChange, List.of()); - var newid = new ToscaConceptIdentifier("id", "1.2.3"); - stateChange.setControlLoopId(newid); - stateChange.setParticipantId(newid); - assertDoesNotThrow(() -> clh.handleControlLoopStateChange(stateChange, List.of())); - - var cld = new ControlLoopElementDefinition(); - cld.setClElementDefinitionId(id); - var updateMsg = new ControlLoopUpdate(); - updateMsg.setControlLoopId(id); - updateMsg.setMessageId(uuid); - updateMsg.setParticipantId(id); - updateMsg.setStartPhase(0); - var clElementDefinitions = List.of(cld); - assertDoesNotThrow(() -> clh.handleControlLoopUpdate(updateMsg, clElementDefinitions)); - updateMsg.setStartPhase(1); - assertDoesNotThrow(() -> clh.handleControlLoopUpdate(updateMsg, clElementDefinitions)); - assertThat(clh.getClElementInstanceProperties(uuid)).isEmpty(); - - clh.getControlLoopMap().clear(); - updateMsg.setStartPhase(0); - assertDoesNotThrow(() -> clh.handleControlLoopUpdate(updateMsg, clElementDefinitions)); - - updateMsg.setControlLoopId(new ToscaConceptIdentifier("new", "0.0.1")); - updateMsg.setParticipantUpdatesList(List.of(mock(ParticipantUpdates.class))); - assertDoesNotThrow(() -> clh.handleControlLoopUpdate(updateMsg, clElementDefinitions)); - - updateMsg.setStartPhase(1); - var participantUpdate = new ParticipantUpdates(); - participantUpdate.setParticipantId(id); - var element = new ControlLoopElement(); - element.setParticipantType(id); - element.setDefinition(id); - participantUpdate.setControlLoopElementList(List.of(element)); - updateMsg.setParticipantUpdatesList(List.of(participantUpdate)); - - var cld2 = new ControlLoopElementDefinition(); - cld2.setClElementDefinitionId(id); - cld2.setControlLoopElementToscaNodeTemplate(mock(ToscaNodeTemplate.class)); - assertDoesNotThrow(() -> clh.handleControlLoopUpdate(updateMsg, List.of(cld2))); - - } - - @Test - void controlLoopStateChangeUninitialisedTest() throws CoderException { - var uuid = UUID.randomUUID(); - var id = CommonTestData.getParticipantId(); - - var stateChangeUninitialised = getStateChange(id, uuid, ControlLoopOrderedState.UNINITIALISED); - - var clh = commonTestData.setTestControlLoopHandler(id, uuid); - clh.handleControlLoopStateChange(stateChangeUninitialised, List.of()); - var newid = new ToscaConceptIdentifier("id", "1.2.3"); - stateChangeUninitialised.setControlLoopId(newid); - stateChangeUninitialised.setParticipantId(newid); - assertDoesNotThrow(() -> clh.handleControlLoopStateChange(stateChangeUninitialised, List.of())); - } - - @Test - void controlLoopStateChangePassiveTest() throws CoderException { - var uuid = UUID.randomUUID(); - var id = CommonTestData.getParticipantId(); - - var stateChangePassive = getStateChange(id, uuid, ControlLoopOrderedState.PASSIVE); - - var clh = commonTestData.setTestControlLoopHandler(id, uuid); - clh.handleControlLoopStateChange(stateChangePassive, List.of()); - var newid = new ToscaConceptIdentifier("id", "1.2.3"); - stateChangePassive.setControlLoopId(newid); - stateChangePassive.setParticipantId(newid); - assertDoesNotThrow(() -> clh.handleControlLoopStateChange(stateChangePassive, List.of())); - } - - - private ControlLoopStateChange getStateChange(ToscaConceptIdentifier id, UUID uuid, ControlLoopOrderedState state) { - var stateChange = new ControlLoopStateChange(); - stateChange.setControlLoopId(id); - stateChange.setParticipantId(id); - stateChange.setMessageId(uuid); - stateChange.setOrderedState(state); - stateChange.setCurrentState(ControlLoopState.UNINITIALISED); - stateChange.setTimestamp(Instant.ofEpochMilli(3000)); - return stateChange; - } - -} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/DummyParticipantParameters.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/DummyParticipantParameters.java deleted file mode 100644 index d60bb71bc..000000000 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/DummyParticipantParameters.java +++ /dev/null @@ -1,35 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.handler; - -import javax.validation.constraints.NotNull; -import lombok.Getter; -import lombok.Setter; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; - -@Getter -@Setter -public class DummyParticipantParameters implements ParticipantParameters { - - @NotNull - private ParticipantIntermediaryParameters intermediaryParameters; -} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivatorTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivatorTest.java deleted file mode 100644 index 8c400c12f..000000000 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivatorTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.handler; - -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyList; -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.when; - -import java.util.List; -import org.junit.jupiter.api.Test; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatusReq; -import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantStatusReqListener; -import org.onap.policy.clamp.controlloop.participant.intermediary.main.parameters.CommonTestData; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.onap.policy.common.utils.coder.StandardCoderObject; -import org.springframework.context.event.ContextClosedEvent; -import org.springframework.context.event.ContextRefreshedEvent; - -class IntermediaryActivatorTest { - private static final Coder CODER = new StandardCoder(); - - private static final String TOPIC_FIRST = "TOPIC1"; - private static final String TOPIC_SECOND = "TOPIC2"; - - @Test - void testStartAndStop() throws Exception { - ParticipantParameters parameters = CommonTestData.getParticipantParameters(); - - var publisherFirst = spy(mock(Publisher.class)); - var publisherSecond = spy(mock(Publisher.class)); - var publishers = List.of(publisherFirst, publisherSecond); - - var listenerFirst = spy(mock(ParticipantStatusReqListener.class)); - when(listenerFirst.getType()).thenReturn(TOPIC_FIRST); - when(listenerFirst.getScoListener()).thenReturn(listenerFirst); - - var listenerSecond = spy(mock(ParticipantStatusReqListener.class)); - when(listenerSecond.getType()).thenReturn(TOPIC_SECOND); - when(listenerSecond.getScoListener()).thenReturn(listenerSecond); - - List> listeners = List.of(listenerFirst, listenerSecond); - - ParticipantHandler handler = mock(ParticipantHandler.class); - try (var activator = new IntermediaryActivator(parameters, handler, publishers, listeners)) { - - assertFalse(activator.isAlive()); - activator.start(); - assertTrue(activator.isAlive()); - - // repeat start - should throw an exception - assertThatIllegalStateException().isThrownBy(() -> activator.start()); - assertTrue(activator.isAlive()); - verify(publisherFirst, times(1)).active(anyList()); - verify(publisherSecond, times(1)).active(anyList()); - - StandardCoderObject sco = CODER.decode("{messageType:" + TOPIC_FIRST + "}", StandardCoderObject.class); - activator.getMsgDispatcher().onTopicEvent(null, "msg", sco); - verify(listenerFirst, times(1)).onTopicEvent(any(), any(), any()); - - sco = CODER.decode("{messageType:" + TOPIC_SECOND + "}", StandardCoderObject.class); - activator.getMsgDispatcher().onTopicEvent(null, "msg", sco); - verify(listenerSecond, times(1)).onTopicEvent(any(), any(), any()); - - activator.close(); - assertFalse(activator.isAlive()); - - // repeat stop - should throw an exception - assertThatIllegalStateException().isThrownBy(() -> activator.stop()); - assertFalse(activator.isAlive()); - - assertDoesNotThrow(() -> activator.handleContextRefreshEvent(mock(ContextRefreshedEvent.class))); - assertDoesNotThrow(() -> activator.handleContextClosedEvent(mock(ContextClosedEvent.class))); - } - } -} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandlerTest.java deleted file mode 100644 index d00697521..000000000 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandlerTest.java +++ /dev/null @@ -1,176 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.handler; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; -import org.junit.jupiter.api.Test; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantHealthStatus; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantState; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantAckMessage; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessage; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegisterAck; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate; -import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantMessagePublisher; -import org.onap.policy.clamp.controlloop.participant.intermediary.main.parameters.CommonTestData; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; - -class ParticipantHandlerTest { - - private CommonTestData commonTestData = new CommonTestData(); - private static final String ID_NAME = "org.onap.PM_CDS_Blueprint"; - private static final String ID_VERSION = "1.0.1"; - - @Test - void mockParticipantHandlerTest() { - var participantHandler = commonTestData.getMockParticipantHandler(); - assertNull(participantHandler.getParticipant(null, null)); - assertEquals("org.onap.PM_CDS_Blueprint 1.0.1", participantHandler.getParticipantId().toString()); - - var id = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); - assertEquals(id, participantHandler.getParticipantId()); - assertEquals(id, participantHandler.getParticipantType()); - assertThat(participantHandler.getClElementDefinitionCommonProperties(id)).isEmpty(); - - } - - @Test - void handleUpdateTest() { - var parameters = CommonTestData.getParticipantParameters(); - var controlLoopHander = commonTestData.getMockControlLoopHandler(); - var publisher = new ParticipantMessagePublisher(); - var emptyParticipantHandler = - new ParticipantHandler(parameters, publisher, controlLoopHander); - var participantUpdateMsg = new ParticipantUpdate(); - - assertThatThrownBy(() -> - emptyParticipantHandler.handleParticipantUpdate(participantUpdateMsg)) - .isInstanceOf(RuntimeException.class); - - var participantHandler = commonTestData.getMockParticipantHandler(); - - var id = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); - participantUpdateMsg.setControlLoopId(id); - participantUpdateMsg.setParticipantId(id); - participantUpdateMsg.setParticipantType(id); - participantUpdateMsg.setMessageId(UUID.randomUUID()); - participantUpdateMsg.setTimestamp(Instant.ofEpochMilli(3000)); - - var heartbeatF = participantHandler.makeHeartbeat(false); - assertEquals(id, heartbeatF.getParticipantId()); - assertEquals(ParticipantState.UNKNOWN, heartbeatF.getParticipantStatistics().getState()); - assertThat(heartbeatF.getControlLoopInfoList()).isEmpty(); - - participantHandler.handleParticipantUpdate(participantUpdateMsg); - assertThat(participantHandler.getClElementDefinitionCommonProperties(id)).isEmpty(); - - var heartbeatT = participantHandler.makeHeartbeat(true); - assertEquals(id, heartbeatT.getParticipantId()); - assertEquals(ParticipantState.TERMINATED, heartbeatT.getParticipantStatistics().getState()); - assertThat(heartbeatT.getParticipantDefinitionUpdates()).isNotEmpty(); - assertEquals(id, heartbeatT.getParticipantDefinitionUpdates().get(0).getParticipantId()); - - var pum = setListParticipantDefinition(participantUpdateMsg); - participantHandler.handleParticipantUpdate(pum); - var heartbeatTAfterUpdate = participantHandler.makeHeartbeat(true); - assertEquals(id, heartbeatTAfterUpdate.getParticipantId()); - assertEquals(ParticipantState.PASSIVE, heartbeatTAfterUpdate.getParticipantStatistics().getState()); - - } - - private ParticipantUpdate setListParticipantDefinition(ParticipantUpdate participantUpdateMsg) { - var id = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); - List participantDefinitionUpdates = new ArrayList<>(); - var def = new ParticipantDefinition(); - def.setParticipantId(id); - def.setParticipantType(id); - participantDefinitionUpdates.add(def); - participantUpdateMsg.setParticipantDefinitionUpdates(participantDefinitionUpdates); - return participantUpdateMsg; - } - - @Test - void handleParticipantTest() { - var participantHandler = commonTestData.getMockParticipantHandler(); - var id = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); - var p = participantHandler.getParticipant(id.getName(), id.getVersion()); - assertEquals(ParticipantState.UNKNOWN, p.getParticipantState()); - - participantHandler.updateParticipantState(id, ParticipantState.PASSIVE); - var p2 = participantHandler.getParticipant(id.getName(), id.getVersion()); - assertEquals(ParticipantState.PASSIVE, p2.getParticipantState()); - - var participantRegisterAckMsg = new ParticipantRegisterAck(); - participantRegisterAckMsg.setState(ParticipantState.TERMINATED); - participantHandler.handleParticipantRegisterAck(participantRegisterAckMsg); - assertEquals(ParticipantHealthStatus.HEALTHY, participantHandler.makeHeartbeat(false).getHealthStatus()); - - var emptyid = new ToscaConceptIdentifier("", ID_VERSION); - assertNull(participantHandler.updateParticipantState(emptyid, ParticipantState.PASSIVE)); - - var sameid = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); - var participant = participantHandler.updateParticipantState(sameid, ParticipantState.PASSIVE); - assertEquals(participant.getDefinition(), sameid); - - } - - @Test - void checkAppliesTo() { - var participantHandler = commonTestData.getMockParticipantHandler(); - var participantAckMsg = - new ParticipantAckMessage(ParticipantMessageType.CONTROL_LOOP_UPDATE); - assertTrue(participantHandler.appliesTo(participantAckMsg)); - - var participantMsg = - new ParticipantMessage(ParticipantMessageType.PARTICIPANT_STATUS); - assertTrue(participantHandler.appliesTo(participantMsg)); - - var emptyid = new ToscaConceptIdentifier("", ID_VERSION); - participantMsg.setParticipantType(emptyid); - assertFalse(participantHandler.appliesTo(participantMsg)); - - } - - @Test - void getControlLoopInfoListTest() throws CoderException { - var participantHandler = commonTestData.getParticipantHandlerControlLoops(); - var id = new ToscaConceptIdentifier(ID_NAME, ID_VERSION); - participantHandler.sendHeartbeat(); - assertEquals(id, participantHandler.makeHeartbeat(false) - .getControlLoopInfoList() - .get(0) - .getControlLoopId()); - - } - -} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/main/parameters/CommonTestData.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/main/parameters/CommonTestData.java deleted file mode 100644 index 9bbf8964c..000000000 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/main/parameters/CommonTestData.java +++ /dev/null @@ -1,293 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.main.parameters; - -import java.io.File; -import java.time.Instant; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import java.util.UUID; -import org.mockito.Mockito; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; -import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregisterAck; -import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantMessagePublisher; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ControlLoopHandler; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.DummyParticipantParameters; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters; -import org.onap.policy.common.endpoints.event.comm.TopicSink; -import org.onap.policy.common.endpoints.parameters.TopicParameters; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; - -/** - * Class to hold/create all parameters for test cases. - */ -public class CommonTestData { - public static final String PARTICIPANT_GROUP_NAME = "ControlLoopParticipantGroup"; - public static final String DESCRIPTION = "Participant description"; - public static final long TIME_INTERVAL = 2000; - public static final List TOPIC_PARAMS = Arrays.asList(getTopicParams()); - public static final Coder CODER = new StandardCoder(); - private static final Object lockit = new Object(); - - /** - * Get ParticipantIntermediaryParameters. - * - * @return ParticipantIntermediaryParameters - */ - public ParticipantIntermediaryParameters getParticipantIntermediaryParameters() { - try { - return CODER.convert(getIntermediaryParametersMap(PARTICIPANT_GROUP_NAME), - ParticipantIntermediaryParameters.class); - } catch (final CoderException e) { - throw new RuntimeException("cannot create ParticipantSimulatorParameters from map", e); - } - } - - /** - * Get ParticipantParameters. - * - * @return ParticipantParameters - */ - public static DummyParticipantParameters getParticipantParameters() { - try { - return CODER.convert(getParametersMap(PARTICIPANT_GROUP_NAME), - DummyParticipantParameters.class); - } catch (final CoderException e) { - throw new RuntimeException("cannot create ParticipantSimulatorParameters from map", e); - } - } - - /** - * Returns a property map for a Parameters map for test cases. - * - * @param name name of the parameters - * @return a property map suitable for constructing an object - */ - public static Map getParametersMap(final String name) { - final Map map = new TreeMap<>(); - map.put("intermediaryParameters", getIntermediaryParametersMap(name)); - return map; - } - - /** - * Returns a property map for a intermediaryParameters map for test cases. - * - * @param name name of the parameters - * @return a property map suitable for constructing an object - */ - public static Map getIntermediaryParametersMap(final String name) { - final Map map = new TreeMap<>(); - map.put("name", name); - map.put("participantId", getParticipantId()); - map.put("description", DESCRIPTION); - map.put("participantType", getParticipantId()); - map.put("reportingTimeIntervalMs", TIME_INTERVAL); - map.put("clampControlLoopTopics", getTopicParametersMap(false)); - - return map; - } - - /** - * Returns a property map for a TopicParameters map for test cases. - * - * @param isEmpty boolean value to represent that object created should be empty or not - * @return a property map suitable for constructing an object - */ - public static Map getTopicParametersMap(final boolean isEmpty) { - final Map map = new TreeMap<>(); - if (!isEmpty) { - map.put("topicSources", TOPIC_PARAMS); - map.put("topicSinks", TOPIC_PARAMS); - } - return map; - } - - /** - * Returns topic parameters for test cases. - * - * @return topic parameters - */ - public static TopicParameters getTopicParams() { - final var topicParams = new TopicParameters(); - topicParams.setTopic("POLICY-CLRUNTIME-PARTICIPANT"); - topicParams.setTopicCommInfrastructure("dmaap"); - topicParams.setServers(Arrays.asList("localhost")); - return topicParams; - } - - /** - * Returns participantId for test cases. - * - * @return participant Id - */ - public static ToscaConceptIdentifier getParticipantId() { - return new ToscaConceptIdentifier("org.onap.PM_CDS_Blueprint", "1.0.1"); - } - - /** - * Returns a participantMessagePublisher for MessageSender. - * - * @return participant Message Publisher - */ - private ParticipantMessagePublisher getParticipantMessagePublisher() { - synchronized (lockit) { - var participantMessagePublisher = new ParticipantMessagePublisher(); - participantMessagePublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class))); - return participantMessagePublisher; - } - } - - /** - * Returns a mocked ControlLoopHandler for test cases. - * - * @return ControlLoopHandler - */ - public ControlLoopHandler getMockControlLoopHandler() { - return new ControlLoopHandler( - getParticipantParameters(), - getParticipantMessagePublisher()); - } - - /** - * Returns a mocked ParticipantHandler for test cases. - * - * @return participant Handler - */ - public ParticipantHandler getMockParticipantHandler() { - var parameters = getParticipantParameters(); - var controlLoopHandler = getMockControlLoopHandler(); - var publisher = new ParticipantMessagePublisher(); - publisher.active(Collections.singletonList(Mockito.mock(TopicSink.class))); - var participantHandler = new ParticipantHandler(parameters, publisher, controlLoopHandler); - return participantHandler; - } - - /** - * Returns a mocked ParticipantHandler for test cases. - * - * @return participant Handler - * - * @throws CoderException if there is an error with .json file. - */ - public ParticipantHandler getParticipantHandlerControlLoops() throws CoderException { - var controlLoopHandler = Mockito.mock(ControlLoopHandler.class); - Mockito.doReturn(getTestControlLoops()).when(controlLoopHandler).getControlLoops(); - Mockito.doReturn(getTestControlLoopMap()).when(controlLoopHandler).getControlLoopMap(); - var publisher = new ParticipantMessagePublisher(); - publisher.active(Collections.singletonList(Mockito.mock(TopicSink.class))); - var parameters = getParticipantParameters(); - var participantHandler = new ParticipantHandler(parameters, publisher, controlLoopHandler); - participantHandler.sendParticipantRegister(); - participantHandler.handleParticipantStatusReq(null); - participantHandler.sendParticipantDeregister(); - var participantDeregisterAckMsg = new ParticipantDeregisterAck(); - participantDeregisterAckMsg.setResponseTo(UUID.randomUUID()); - participantHandler.handleParticipantDeregisterAck(participantDeregisterAckMsg); - return participantHandler; - } - - /** - * Returns a Map of ToscaConceptIdentifier and ControlLoop for test cases. - * - * @return controlLoopMap - * - * @throws CoderException if there is an error with .json file. - */ - public Map getTestControlLoopMap() throws CoderException { - var controlLoops = getTestControlLoops(); - var controlLoop = controlLoops.getControlLoopList().get(1); - var id = getParticipantId(); - Map controlLoopMap = new LinkedHashMap<>(); - controlLoopMap.put(id, controlLoop); - return controlLoopMap; - } - - /** - * Returns List of ControlLoop for test cases. - * - * @return ControlLoops - * - * @throws CoderException if there is an error with .json file. - */ - public ControlLoops getTestControlLoops() throws CoderException { - return new StandardCoder() - .decode(new File("src/test/resources/providers/TestControlLoops.json"), ControlLoops.class); - } - - /** - * Returns a map for a elementsOnThisParticipant for test cases. - * - * @param uuid UUID and id ToscaConceptIdentifier - * @return a map suitable for elementsOnThisParticipant - */ - public Map setControlLoopElementTest(UUID uuid, ToscaConceptIdentifier id) { - var clElement = new ControlLoopElement(); - clElement.setId(uuid); - clElement.setParticipantId(id); - clElement.setDefinition(id); - clElement.setOrderedState(ControlLoopOrderedState.UNINITIALISED); - - var clElementStatistics = new ClElementStatistics(); - clElementStatistics.setParticipantId(id); - clElementStatistics.setControlLoopState(ControlLoopState.UNINITIALISED); - clElementStatistics.setTimeStamp(Instant.now()); - - clElement.setClElementStatistics(clElementStatistics); - - Map elementsOnThisParticipant = new LinkedHashMap<>(); - elementsOnThisParticipant.put(uuid, clElement); - return elementsOnThisParticipant; - } - - /** - * Returns a ControlLoopHandler with elements on the id,uuid. - * - * @param id ToscaConceptIdentifier and uuid UUID - * @return a ControlLoopHander with elements - */ - public ControlLoopHandler setTestControlLoopHandler(ToscaConceptIdentifier id, UUID uuid) throws CoderException { - var clh = getMockControlLoopHandler(); - - var key = getTestControlLoopMap().keySet().iterator().next(); - var value = getTestControlLoopMap().get(key); - clh.getControlLoopMap().put(key, value); - - var keyElem = setControlLoopElementTest(uuid, id).keySet().iterator().next(); - var valueElem = setControlLoopElementTest(uuid, id).get(keyElem); - clh.getElementsOnThisParticipant().put(keyElem, valueElem); - - return clh; - } - -} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/main/parameters/TestParticipantIntermediaryParameters.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/main/parameters/TestParticipantIntermediaryParameters.java deleted file mode 100644 index d554a55b6..000000000 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/main/parameters/TestParticipantIntermediaryParameters.java +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 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.onap.policy.clamp.controlloop.participant.intermediary.main.parameters; - -import static org.assertj.core.api.Assertions.assertThat; - -import javax.validation.Validation; -import javax.validation.ValidatorFactory; -import org.junit.jupiter.api.Test; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters; - -/** - * Class to perform unit test of {@link ParticipantParameterGroup}. - */ -class TestParticipantIntermediaryParameters { - private CommonTestData commonTestData = new CommonTestData(); - private ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); - - @Test - void testParticipantIntermediaryParameterGroup() { - final ParticipantIntermediaryParameters participantParameters = - commonTestData.getParticipantIntermediaryParameters(); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isEmpty(); - } - - @Test - void testParticipantIntermediaryParameterGroup_EmptyParameter() { - final ParticipantIntermediaryParameters participantParameters = - commonTestData.getParticipantIntermediaryParameters(); - participantParameters.setClampControlLoopTopics(null); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); - } - - @Test - void testParticipantIntermediaryParameters_NullTopicSinks() { - final ParticipantIntermediaryParameters participantParameters = - commonTestData.getParticipantIntermediaryParameters(); - participantParameters.getClampControlLoopTopics().setTopicSinks(null); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); - } - - @Test - void testParticipantIntermediaryParameters_NullTopicSources() { - final ParticipantIntermediaryParameters participantParameters = - commonTestData.getParticipantIntermediaryParameters(); - participantParameters.getClampControlLoopTopics().setTopicSources(null); - assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); - } -} diff --git a/participant/participant-intermediary/src/test/resources/providers/TestAutomationCompositions.json b/participant/participant-intermediary/src/test/resources/providers/TestAutomationCompositions.json new file mode 100644 index 000000000..4e0f08981 --- /dev/null +++ b/participant/participant-intermediary/src/test/resources/providers/TestAutomationCompositions.json @@ -0,0 +1,142 @@ +{ + "automationCompositionList": [ + { + "definition": { + "name": "org.onap.domain.pmsh.PMSHAutomationCompositionDefinition", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "elements": { + "709c62b3-8918-41b9-a747-e21eb79c6c20": { + "id": "709c62b3-8918-41b9-a747-d21eb79c6c20", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice", + "version": "1.2.3" + }, + "participantType": { + "name": "org.onap.dcae.acm.DCAEMicroserviceAutomationCompositionParticipant", + "version": "2.3.4" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "DCAE Automation Composition Element for the PMSH instance 0 automation composition" + }, + "709c62b3-8918-41b9-a747-e21eb79c6c21": { + "id": "709c62b3-8918-41b9-a747-d21eb79c6c21", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyAutomationCompositionElement", + "version": "1.2.3" + }, + "participantType": { + "name": "org.onap.policy.acm.PolicyAutomationCompositionParticipant", + "version": "2.3.1" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "Monitoring Policy Automation Composition Element for the PMSH instance 0 automation composition" + }, + "709c62b3-8918-41b9-a747-e21eb79c6c22": { + "id": "709c62b3-8918-41b9-a747-d21eb79c6c22", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyAutomationCompositionElement", + "version": "1.2.3" + }, + "participantType": { + "name": "org.onap.policy.acm.PolicyAutomationCompositionParticipant", + "version": "2.3.1" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "Operational Policy Automation Composition Element for the PMSH instance 0 automation composition" + }, + "709c62b3-8918-41b9-a747-e21eb79c6c23": { + "id": "709c62b3-8918-41b9-a747-d21eb79c6c23", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_CDS_AutomationCompositionElement", + "version": "1.2.3" + }, + "participantType": { + "name": "org.onap.ccsdk.cds.acm.CdsAutomationCompositionParticipant", + "version": "2.2.1" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "CDS Automation Composition Element for the PMSH instance 0 automation composition" + } + }, + "name": "PMSHInstance0", + "version": "1.0.1", + "description": "PMSH automation composition instance 0" + }, + { + "definition": { + "name": "org.onap.domain.pmsh.PMSHAutomationCompositionDefinition", + "version": "1.0.0" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "elements": { + "709c62b3-8918-41b9-a747-e21eb79c6c24": { + "id": "709c62b3-8918-41b9-a747-e21eb79c6c24", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice", + "version": "1.2.3" + }, + "participantType": { + "name": "org.onap.dcae.acm.DCAEMicroserviceAutomationCompositionParticipant", + "version": "2.3.4" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "DCAE Automation Composition Element for the PMSH instance 1 automation composition" + }, + "709c62b3-8918-41b9-a747-e21eb79c6c25": { + "id": "709c62b3-8918-41b9-a747-e21eb79c6c25", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyAutomationCompositionElement", + "version": "1.2.3" + }, + "participantType": { + "name": "org.onap.policy.acm.PolicyAutomationCompositionParticipant", + "version": "2.3.1" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "Monitoring Policy Automation Composition Element for the PMSH instance 1 automation composition" + }, + "709c62b3-8918-41b9-a747-e21eb79c6c26": { + "id": "709c62b3-8918-41b9-a747-e21eb79c6c26", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyAutomationCompositionElement", + "version": "1.2.3" + }, + "participantType": { + "name": "org.onap.policy.acm.PolicyAutomationCompositionParticipant", + "version": "2.3.1" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "Operational Policy Automation Composition Element for the PMSH instance 1 automation composition" + }, + "709c62b3-8918-41b9-a747-e21eb79c6c27": { + "id": "709c62b3-8918-41b9-a747-e21eb79c6c27", + "definition": { + "name": "org.onap.domain.pmsh.PMSH_CDS_AutomationCompositionElement", + "version": "1.2.3" + }, + "participantType": { + "name": "org.onap.ccsdk.cds.acm.CdsAutomationCompositionParticipant", + "version": "2.2.1" + }, + "state": "UNINITIALISED", + "orderedState": "UNINITIALISED", + "description": "CDS Automation Composition Element for the PMSH instance 1 automation composition" + } + }, + "name": "PMSHInstance1", + "version": "1.0.1", + "description": "PMSH automation composition instance 1" + } + ] +} diff --git a/participant/participant-intermediary/src/test/resources/providers/TestControlLoops.json b/participant/participant-intermediary/src/test/resources/providers/TestControlLoops.json deleted file mode 100644 index fedda9600..000000000 --- a/participant/participant-intermediary/src/test/resources/providers/TestControlLoops.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "controlLoopList": [ - { - "definition": { - "name": "org.onap.domain.pmsh.PMSHControlLoopDefinition", - "version": "1.0.0" - }, - "state": "UNINITIALISED", - "orderedState": "UNINITIALISED", - "elements": { - "709c62b3-8918-41b9-a747-e21eb79c6c20": { - "id": "709c62b3-8918-41b9-a747-d21eb79c6c20", - "definition": { - "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice", - "version": "1.2.3" - }, - "participantType": { - "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant", - "version": "2.3.4" - }, - "state": "UNINITIALISED", - "orderedState": "UNINITIALISED", - "description": "DCAE Control Loop Element for the PMSH instance 0 control loop" - }, - "709c62b3-8918-41b9-a747-e21eb79c6c21": { - "id": "709c62b3-8918-41b9-a747-d21eb79c6c21", - "definition": { - "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement", - "version": "1.2.3" - }, - "participantType": { - "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant", - "version": "2.3.1" - }, - "state": "UNINITIALISED", - "orderedState": "UNINITIALISED", - "description": "Monitoring Policy Control Loop Element for the PMSH instance 0 control loop" - }, - "709c62b3-8918-41b9-a747-e21eb79c6c22": { - "id": "709c62b3-8918-41b9-a747-d21eb79c6c22", - "definition": { - "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement", - "version": "1.2.3" - }, - "participantType": { - "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant", - "version": "2.3.1" - }, - "state": "UNINITIALISED", - "orderedState": "UNINITIALISED", - "description": "Operational Policy Control Loop Element for the PMSH instance 0 control loop" - }, - "709c62b3-8918-41b9-a747-e21eb79c6c23": { - "id": "709c62b3-8918-41b9-a747-d21eb79c6c23", - "definition": { - "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement", - "version": "1.2.3" - }, - "participantType": { - "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant", - "version": "2.2.1" - }, - "state": "UNINITIALISED", - "orderedState": "UNINITIALISED", - "description": "CDS Control Loop Element for the PMSH instance 0 control loop" - } - }, - "name": "PMSHInstance0", - "version": "1.0.1", - "description": "PMSH control loop instance 0" - }, - { - "definition": { - "name": "org.onap.domain.pmsh.PMSHControlLoopDefinition", - "version": "1.0.0" - }, - "state": "UNINITIALISED", - "orderedState": "UNINITIALISED", - "elements": { - "709c62b3-8918-41b9-a747-e21eb79c6c24": { - "id": "709c62b3-8918-41b9-a747-e21eb79c6c24", - "definition": { - "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice", - "version": "1.2.3" - }, - "participantType": { - "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant", - "version": "2.3.4" - }, - "state": "UNINITIALISED", - "orderedState": "UNINITIALISED", - "description": "DCAE Control Loop Element for the PMSH instance 1 control loop" - }, - "709c62b3-8918-41b9-a747-e21eb79c6c25": { - "id": "709c62b3-8918-41b9-a747-e21eb79c6c25", - "definition": { - "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement", - "version": "1.2.3" - }, - "participantType": { - "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant", - "version": "2.3.1" - }, - "state": "UNINITIALISED", - "orderedState": "UNINITIALISED", - "description": "Monitoring Policy Control Loop Element for the PMSH instance 1 control loop" - }, - "709c62b3-8918-41b9-a747-e21eb79c6c26": { - "id": "709c62b3-8918-41b9-a747-e21eb79c6c26", - "definition": { - "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement", - "version": "1.2.3" - }, - "participantType": { - "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant", - "version": "2.3.1" - }, - "state": "UNINITIALISED", - "orderedState": "UNINITIALISED", - "description": "Operational Policy Control Loop Element for the PMSH instance 1 control loop" - }, - "709c62b3-8918-41b9-a747-e21eb79c6c27": { - "id": "709c62b3-8918-41b9-a747-e21eb79c6c27", - "definition": { - "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement", - "version": "1.2.3" - }, - "participantType": { - "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant", - "version": "2.2.1" - }, - "state": "UNINITIALISED", - "orderedState": "UNINITIALISED", - "description": "CDS Control Loop Element for the PMSH instance 1 control loop" - } - }, - "name": "PMSHInstance1", - "version": "1.0.1", - "description": "PMSH control loop instance 1" - } - ] -} -- cgit 1.2.3-korg