bdf4f8fcf650b769216b52854c1471382a154a6c
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021,2022 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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  * SPDX-License-Identifier: Apache-2.0
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.policy.clamp.acm.participant.policy.main.handler;
24
25 import java.util.LinkedHashMap;
26 import java.util.Map;
27 import java.util.Map.Entry;
28 import java.util.UUID;
29 import lombok.Setter;
30 import org.apache.http.HttpStatus;
31 import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener;
32 import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
33 import org.onap.policy.clamp.acm.participant.policy.client.PolicyApiHttpClient;
34 import org.onap.policy.clamp.acm.participant.policy.client.PolicyPapHttpClient;
35 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
36 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState;
37 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState;
38 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType;
39 import org.onap.policy.models.base.PfModelException;
40 import org.onap.policy.models.base.PfModelRuntimeException;
41 import org.onap.policy.models.pdp.concepts.DeploymentSubGroup;
42 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
43 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
44 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
45 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
46 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49 import org.springframework.stereotype.Component;
50
51 /**
52  * This class handles implementation of automationCompositionElement updates.
53  */
54 @Component
55 public class AutomationCompositionElementHandler implements AutomationCompositionElementListener {
56
57     private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionElementHandler.class);
58     private final Map<String, String> policyTypeMap = new LinkedHashMap<>();
59     private final Map<String, String> policyMap = new LinkedHashMap<>();
60
61     private final PolicyApiHttpClient apiHttpClient;
62     private final PolicyPapHttpClient papHttpClient;
63
64     @Setter
65     private ParticipantIntermediaryApi intermediaryApi;
66
67     /**
68      * constructor.
69      *
70      * @param apiHttpClient the Policy Api Http Client
71      * @param papHttpClient the Policy Pap Http Client
72      */
73     public AutomationCompositionElementHandler(PolicyApiHttpClient apiHttpClient, PolicyPapHttpClient papHttpClient) {
74         this.papHttpClient = papHttpClient;
75         this.apiHttpClient = apiHttpClient;
76     }
77
78     /**
79      * Callback method to handle a automation composition element state change.
80      *
81      * @param automationCompositionId        the ID of the automation composition
82      * @param automationCompositionElementId the ID of the automation composition element
83      * @param currentState                   the current state of the automation composition element
84      * @param orderedState                   the state to which the automation composition element is changing to
85      */
86     @Override
87     public void automationCompositionElementStateChange(ToscaConceptIdentifier automationCompositionId,
88                                                         UUID automationCompositionElementId,
89                                                         AutomationCompositionState currentState,
90                                                         AutomationCompositionOrderedState orderedState) {
91         switch (orderedState) {
92             case UNINITIALISED:
93                 try {
94                     undeployPolicies(automationCompositionElementId);
95                     deletePolicyData(automationCompositionId, automationCompositionElementId, orderedState);
96                     intermediaryApi.updateAutomationCompositionElementState(automationCompositionId,
97                         automationCompositionElementId, orderedState, AutomationCompositionState.UNINITIALISED,
98                         ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE);
99                 } catch (PfModelRuntimeException e) {
100                     LOGGER.error("Undeploying/Deleting policy failed {}", automationCompositionElementId, e);
101                 }
102                 break;
103             case PASSIVE:
104                 try {
105                     undeployPolicies(automationCompositionElementId);
106                 } catch (PfModelRuntimeException e) {
107                     LOGGER.error("Undeploying policies failed - no policies to undeploy {}",
108                         automationCompositionElementId);
109                 }
110                 intermediaryApi.updateAutomationCompositionElementState(automationCompositionId,
111                     automationCompositionElementId, orderedState, AutomationCompositionState.PASSIVE,
112                     ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE);
113                 break;
114             case RUNNING:
115                 LOGGER.info("Running state is not supported");
116                 break;
117             default:
118                 LOGGER.debug("Unknown orderedstate {}", orderedState);
119                 break;
120         }
121     }
122
123     private void deletePolicyData(ToscaConceptIdentifier automationCompositionId,
124                                   UUID automationCompositionElementId, AutomationCompositionOrderedState newState) {
125         // Delete all policies of this automationComposition from policy framework
126         for (Entry<String, String> policy : policyMap.entrySet()) {
127             apiHttpClient.deletePolicy(policy.getKey(), policy.getValue());
128         }
129         policyMap.clear();
130         // Delete all policy types of this automation composition from policy framework
131         for (Entry<String, String> policyType : policyTypeMap.entrySet()) {
132             apiHttpClient.deletePolicyType(policyType.getKey(), policyType.getValue());
133         }
134         policyTypeMap.clear();
135     }
136
137     private void deployPolicies(ToscaConceptIdentifier automationCompositionId, UUID automationCompositionElementId,
138                                 AutomationCompositionOrderedState newState) {
139         var deployFailure = false;
140         // Deploy all policies of this automationComposition from Policy Framework
141         if (!policyMap.entrySet().isEmpty()) {
142             for (Entry<String, String> policy : policyMap.entrySet()) {
143                 var deployPolicyResp = papHttpClient.handlePolicyDeployOrUndeploy(policy.getKey(), policy.getValue(),
144                         DeploymentSubGroup.Action.POST).getStatus();
145                 if (deployPolicyResp != HttpStatus.SC_ACCEPTED) {
146                     deployFailure = true;
147                 }
148             }
149             LOGGER.info("Policies deployed to {} successfully", automationCompositionElementId);
150         } else {
151             LOGGER.debug("No policies to deploy to {}", automationCompositionElementId);
152         }
153         if (! deployFailure) {
154             // Update the AC element state
155             intermediaryApi.updateAutomationCompositionElementState(automationCompositionId,
156                     automationCompositionElementId, newState, AutomationCompositionState.PASSIVE,
157                     ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE);
158         }
159     }
160
161     private void undeployPolicies(UUID automationCompositionElementId) {
162         // Undeploy all policies of this automation composition from Policy Framework
163         if (!policyMap.entrySet().isEmpty()) {
164             for (Entry<String, String> policy : policyMap.entrySet()) {
165                 papHttpClient.handlePolicyDeployOrUndeploy(policy.getKey(), policy.getValue(),
166                     DeploymentSubGroup.Action.DELETE);
167             }
168             LOGGER.debug("Undeployed policies from {} successfully", automationCompositionElementId);
169         } else {
170             LOGGER.debug("No policies are deployed to {}", automationCompositionElementId);
171         }
172     }
173
174     /**
175      * Callback method to handle an update on automation composition element.
176      *
177      * @param element the information on the automation composition element
178      * @param acElementDefinition toscaNodeTemplate
179      * @throws PfModelException in case of an exception
180      */
181     @Override
182     public void automationCompositionElementUpdate(ToscaConceptIdentifier automationCompositionId,
183                                                    AutomationCompositionElement element,
184                                                    ToscaNodeTemplate acElementDefinition)
185         throws PfModelException {
186         var createPolicyTypeResp = HttpStatus.SC_OK;
187         var createPolicyResp = HttpStatus.SC_OK;
188
189         ToscaServiceTemplate automationCompositionDefinition = element.getToscaServiceTemplateFragment();
190         if (automationCompositionDefinition.getToscaTopologyTemplate() != null) {
191             if (automationCompositionDefinition.getPolicyTypes() != null) {
192                 for (ToscaPolicyType policyType : automationCompositionDefinition.getPolicyTypes().values()) {
193                     policyTypeMap.put(policyType.getName(), policyType.getVersion());
194                 }
195                 LOGGER.info("Found Policy Types in automation composition definition: {} , Creating Policy Types",
196                     automationCompositionDefinition.getName());
197                 createPolicyTypeResp = apiHttpClient.createPolicyType(automationCompositionDefinition).getStatus();
198             }
199             if (automationCompositionDefinition.getToscaTopologyTemplate().getPolicies() != null) {
200                 for (Map<String, ToscaPolicy> gotPolicyMap : automationCompositionDefinition.getToscaTopologyTemplate()
201                     .getPolicies()) {
202                     for (ToscaPolicy policy : gotPolicyMap.values()) {
203                         policyMap.put(policy.getName(), policy.getVersion());
204                     }
205                 }
206                 LOGGER.info("Found Policies in automation composition definition: {} , Creating Policies",
207                     automationCompositionDefinition.getName());
208                 createPolicyResp = apiHttpClient.createPolicy(automationCompositionDefinition).getStatus();
209             }
210             if (createPolicyTypeResp == HttpStatus.SC_OK && createPolicyResp == HttpStatus.SC_OK) {
211                 LOGGER.info("PolicyTypes/Policies for the automation composition element : {} are created "
212                         + "successfully", element.getId());
213                 deployPolicies(automationCompositionId, element.getId(), element.getOrderedState());
214             } else {
215                 LOGGER.error("Creation of PolicyTypes/Policies failed. Policies will not be deployed.");
216             }
217         }
218     }
219 }