2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2021-2024 Nordix Foundation.
4 * ================================================================================
5 * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * SPDX-License-Identifier: Apache-2.0
20 * ============LICENSE_END=========================================================
23 package org.onap.policy.clamp.acm.participant.policy.main.handler;
25 import jakarta.ws.rs.core.Response.Status;
26 import java.util.ArrayList;
27 import java.util.List;
29 import java.util.UUID;
30 import org.apache.http.HttpStatus;
31 import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto;
32 import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto;
33 import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
34 import org.onap.policy.clamp.acm.participant.intermediary.api.impl.AcElementListenerV2;
35 import org.onap.policy.clamp.acm.participant.policy.client.PolicyApiHttpClient;
36 import org.onap.policy.clamp.acm.participant.policy.client.PolicyPapHttpClient;
37 import org.onap.policy.clamp.models.acm.concepts.DeployState;
38 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
39 import org.onap.policy.models.base.PfModelException;
40 import org.onap.policy.models.pdp.concepts.DeploymentSubGroup;
41 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
42 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45 import org.springframework.stereotype.Component;
48 * This class handles implementation of automationCompositionElement updates.
51 public class AutomationCompositionElementHandler extends AcElementListenerV2 {
53 private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionElementHandler.class);
55 private final PolicyApiHttpClient apiHttpClient;
56 private final PolicyPapHttpClient papHttpClient;
61 * @param apiHttpClient the PolicyApi Http Client
62 * @param papHttpClient the Policy Pap Http Client
63 * @param intermediaryApi the Participant Intermediary Api
65 public AutomationCompositionElementHandler(PolicyApiHttpClient apiHttpClient, PolicyPapHttpClient papHttpClient,
66 ParticipantIntermediaryApi intermediaryApi) {
67 super(intermediaryApi);
68 this.apiHttpClient = apiHttpClient;
69 this.papHttpClient = papHttpClient;
73 * Callback method to handle a automation composition element state change.
75 * @param compositionElement the information of the Automation Composition Definition Element
76 * @param instanceElement the information of the Automation Composition Instance Element
77 * @throws PfModelException in case of a model exception
80 public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
81 throws PfModelException {
82 var automationCompositionDefinition = instanceElement.toscaServiceTemplateFragment();
83 if (automationCompositionDefinition.getToscaTopologyTemplate() == null) {
84 LOGGER.debug("No policies to undeploy to {}", instanceElement.elementId());
85 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
86 instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR,
90 var policyList = getPolicyList(automationCompositionDefinition);
91 undeployPolicies(policyList, instanceElement.elementId());
92 var policyTypeList = getPolicyTypeList(automationCompositionDefinition);
93 deletePolicyData(policyTypeList, policyList);
94 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
95 instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR,
99 private void deletePolicyData(List<ToscaConceptIdentifier> policyTypeList,
100 List<ToscaConceptIdentifier> policyList) {
101 // Delete all policies of this automationComposition from policy framework
102 for (var policy : policyList) {
103 apiHttpClient.deletePolicy(policy.getName(), policy.getVersion());
105 // Delete all policy types of this automation composition from policy framework
106 for (var policyType : policyTypeList) {
107 apiHttpClient.deletePolicyType(policyType.getName(), policyType.getVersion());
111 private void deployPolicies(List<ToscaConceptIdentifier> policyList, UUID automationCompositionId,
112 UUID automationCompositionElementId) throws PfModelException {
113 var deployFailure = false;
114 // Deploy all policies of this automationComposition from Policy Framework
115 if (!policyList.isEmpty()) {
116 for (var policy : policyList) {
117 var deployPolicyResp = papHttpClient.handlePolicyDeployOrUndeploy(policy.getName(), policy.getVersion(),
118 DeploymentSubGroup.Action.POST).getStatus();
119 if (deployPolicyResp != HttpStatus.SC_ACCEPTED) {
120 deployFailure = true;
123 LOGGER.info("Policies deployed to {} successfully", automationCompositionElementId);
125 LOGGER.debug("No policies to deploy to {}", automationCompositionElementId);
127 if (!deployFailure) {
128 // Update the AC element state
129 intermediaryApi.sendAcElementInfo(automationCompositionId, automationCompositionElementId, "IDLE",
130 "ENABLED", Map.of());
131 intermediaryApi.updateAutomationCompositionElementState(automationCompositionId,
132 automationCompositionElementId, DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed");
134 throw new PfModelException(Status.BAD_REQUEST, "Deploy of Policy failed.");
138 private void undeployPolicies(List<ToscaConceptIdentifier> policyList, UUID automationCompositionElementId) {
139 // Undeploy all policies of this automation composition from Policy Framework
140 if (!policyList.isEmpty()) {
141 for (var policy : policyList) {
142 papHttpClient.handlePolicyDeployOrUndeploy(policy.getName(), policy.getVersion(),
143 DeploymentSubGroup.Action.DELETE);
145 LOGGER.debug("Undeployed policies from {} successfully", automationCompositionElementId);
147 LOGGER.debug("No policies are deployed to {}", automationCompositionElementId);
152 * Callback method to handle an update on automation composition element.
154 * @param compositionElement the information of the Automation Composition Definition Element
155 * @param instanceElement the information of the Automation Composition Instance Element
156 * @throws PfModelException from Policy framework
159 public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
160 throws PfModelException {
161 var createPolicyTypeResp = HttpStatus.SC_OK;
162 var createPolicyResp = HttpStatus.SC_OK;
164 var automationCompositionDefinition = instanceElement.toscaServiceTemplateFragment();
165 if (automationCompositionDefinition.getToscaTopologyTemplate() == null) {
166 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
167 instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
168 "ToscaTopologyTemplate not defined");
171 if (automationCompositionDefinition.getPolicyTypes() != null) {
172 LOGGER.info("Found Policy Types in automation composition definition: {} , Creating Policy Types",
173 automationCompositionDefinition.getName());
174 try (var response = apiHttpClient.createPolicyType(automationCompositionDefinition)) {
175 createPolicyTypeResp = response.getStatus();
178 if (automationCompositionDefinition.getToscaTopologyTemplate().getPolicies() != null) {
179 LOGGER.info("Found Policies in automation composition definition: {} , Creating Policies",
180 automationCompositionDefinition.getName());
181 try (var response = apiHttpClient.createPolicy(automationCompositionDefinition)) {
182 createPolicyResp = response.getStatus();
185 if (createPolicyTypeResp == HttpStatus.SC_OK && createPolicyResp == HttpStatus.SC_OK) {
187 "PolicyTypes/Policies for the automation composition element : {} are created " + "successfully",
188 instanceElement.elementId());
189 var policyList = getPolicyList(automationCompositionDefinition);
190 deployPolicies(policyList, instanceElement.instanceId(), instanceElement.elementId());
192 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
193 instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
194 "Creation of PolicyTypes/Policies failed. Policies will not be deployed.");
198 private List<ToscaConceptIdentifier> getPolicyTypeList(ToscaServiceTemplate serviceTemplate) {
199 List<ToscaConceptIdentifier> policyTypeList = new ArrayList<>();
200 if (serviceTemplate.getPolicyTypes() != null) {
201 for (var policyType : serviceTemplate.getPolicyTypes().values()) {
202 policyTypeList.add(policyType.getKey().asIdentifier());
206 return policyTypeList;
209 private List<ToscaConceptIdentifier> getPolicyList(ToscaServiceTemplate serviceTemplate) {
210 List<ToscaConceptIdentifier> policyList = new ArrayList<>();
211 if (serviceTemplate.getToscaTopologyTemplate().getPolicies() != null) {
212 for (var gotPolicyMap : serviceTemplate.getToscaTopologyTemplate().getPolicies()) {
213 for (var policy : gotPolicyMap.values()) {
214 policyList.add(policy.getKey().asIdentifier());