eaf94552ba163adfb13512e3d0a0cc62fd037dd1
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2023 Nordix Foundation.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.clamp.acm.participant.sim.main.handler;
22
23 import java.lang.invoke.MethodHandles;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.UUID;
28 import lombok.Getter;
29 import lombok.RequiredArgsConstructor;
30 import lombok.Setter;
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.sim.model.InternalData;
34 import org.onap.policy.clamp.acm.participant.sim.model.InternalDatas;
35 import org.onap.policy.clamp.acm.participant.sim.model.SimConfig;
36 import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
37 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
38 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
39 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions;
40 import org.onap.policy.clamp.models.acm.concepts.DeployState;
41 import org.onap.policy.clamp.models.acm.concepts.LockState;
42 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
43 import org.onap.policy.clamp.models.acm.utils.AcmUtils;
44 import org.onap.policy.models.base.PfModelException;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47 import org.springframework.stereotype.Component;
48
49 /**
50  * This class handles implementation of automationCompositionElement updates.
51  */
52 @Component
53 @RequiredArgsConstructor
54 public class AutomationCompositionElementHandler implements AutomationCompositionElementListener {
55
56     private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
57
58     private final ParticipantIntermediaryApi intermediaryApi;
59
60     @Getter
61     @Setter
62     private SimConfig config = new SimConfig();
63
64     /**
65      * Callback method to handle an update on a automation composition element.
66      *
67      * @param automationCompositionId the automationComposition Id
68      * @param element the information on the automation composition element
69      * @param properties properties Map
70      * @throws PfModelException in case of a exception
71      */
72     @Override
73     public void deploy(UUID automationCompositionId, AcElementDeploy element, Map<String, Object> properties)
74             throws PfModelException {
75         LOGGER.debug("deploy call");
76
77         if (!execution(config.getDeployTimerMs(), "Current Thread deploy is Interrupted during execution {}",
78                 element.getId())) {
79             return;
80         }
81
82         if (config.isDeploySuccess()) {
83             intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(),
84                     DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed");
85         } else {
86             intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(),
87                     DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Deploy failed!");
88         }
89     }
90
91     private boolean execution(int timeMs, String msg, UUID elementId) {
92         long endTime = System.currentTimeMillis() + timeMs;
93         while (System.currentTimeMillis() < endTime) {
94             try {
95                 if (Thread.currentThread().isInterrupted()) {
96                     LOGGER.debug(msg, elementId);
97                     return false;
98                 }
99                 Thread.sleep(10L);
100             } catch (InterruptedException e) {
101                 LOGGER.debug(msg, elementId);
102                 Thread.currentThread().interrupt();
103                 return false;
104             }
105         }
106         return true;
107     }
108
109     /**
110      * Handle a automation composition element state change.
111      *
112      * @param automationCompositionElementId the ID of the automation composition element
113      */
114     @Override
115     public void undeploy(UUID automationCompositionId, UUID automationCompositionElementId) throws PfModelException {
116         LOGGER.debug("undeploy call");
117
118         if (!execution(config.getUndeployTimerMs(), "Current Thread undeploy is Interrupted during execution {}",
119                 automationCompositionElementId)) {
120             return;
121         }
122
123         if (config.isUndeploySuccess()) {
124             intermediaryApi.updateAutomationCompositionElementState(automationCompositionId,
125                     automationCompositionElementId, DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR,
126                     "Undeployed");
127         } else {
128             intermediaryApi.updateAutomationCompositionElementState(automationCompositionId,
129                     automationCompositionElementId, DeployState.DEPLOYED, null, StateChangeResult.FAILED,
130                     "Undeploy failed!");
131         }
132     }
133
134     @Override
135     public void lock(UUID automationCompositionId, UUID automationCompositionElementId) throws PfModelException {
136         LOGGER.debug("lock call");
137
138         if (!execution(config.getLockTimerMs(), "Current Thread lock is Interrupted during execution {}",
139                 automationCompositionElementId)) {
140             return;
141         }
142
143         if (config.isLockSuccess()) {
144             intermediaryApi.updateAutomationCompositionElementState(automationCompositionId,
145                     automationCompositionElementId, null, LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked");
146         } else {
147             intermediaryApi.updateAutomationCompositionElementState(automationCompositionId,
148                     automationCompositionElementId, null, LockState.UNLOCKED, StateChangeResult.FAILED, "Lock failed!");
149         }
150     }
151
152     @Override
153     public void unlock(UUID automationCompositionId, UUID automationCompositionElementId) throws PfModelException {
154         LOGGER.debug("unlock call");
155
156         if (!execution(config.getUnlockTimerMs(), "Current Thread unlock is Interrupted during execution {}",
157                 automationCompositionElementId)) {
158             return;
159         }
160
161         if (config.isUnlockSuccess()) {
162             intermediaryApi.updateAutomationCompositionElementState(automationCompositionId,
163                     automationCompositionElementId, null, LockState.UNLOCKED, StateChangeResult.NO_ERROR, "Unlocked");
164         } else {
165             intermediaryApi.updateAutomationCompositionElementState(automationCompositionId,
166                     automationCompositionElementId, null, LockState.LOCKED, StateChangeResult.FAILED, "Unlock failed!");
167         }
168     }
169
170     @Override
171     public void delete(UUID automationCompositionId, UUID automationCompositionElementId) throws PfModelException {
172         LOGGER.debug("delete call");
173
174         if (!execution(config.getDeleteTimerMs(), "Current Thread delete is Interrupted during execution {}",
175                 automationCompositionElementId)) {
176             return;
177         }
178
179         if (config.isDeleteSuccess()) {
180             intermediaryApi.updateAutomationCompositionElementState(automationCompositionId,
181                     automationCompositionElementId, DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted");
182         } else {
183             intermediaryApi.updateAutomationCompositionElementState(automationCompositionId,
184                     automationCompositionElementId, DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
185                     "Delete failed!");
186         }
187     }
188
189     @Override
190     public void update(UUID automationCompositionId, AcElementDeploy element, Map<String, Object> properties)
191             throws PfModelException {
192         LOGGER.debug("update call");
193
194         if (!execution(config.getUpdateTimerMs(), "Current Thread update is Interrupted during execution {}",
195                 element.getId())) {
196             return;
197         }
198
199         if (config.isUpdateSuccess()) {
200             intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(),
201                     DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Updated");
202         } else {
203             intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(),
204                     DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Update failed!");
205         }
206     }
207
208     /**
209      * Get AutomationComposition.
210      *
211      * @return the AutomationCompositions
212      */
213     public AutomationCompositions getAutomationCompositions() {
214         var result = new AutomationCompositions();
215         result.setAutomationCompositionList(new ArrayList<>(intermediaryApi.getAutomationCompositions().values()));
216         return result;
217     }
218
219     /**
220      * Set OutProperties.
221      *
222      * @param automationCompositionId the automationComposition Id
223      * @param elementId the automationComposition Element Id
224      * @param useState the useState
225      * @param operationalState the operationalState
226      * @param outProperties the outProperties
227      */
228     public void setOutProperties(UUID automationCompositionId, UUID elementId, String useState, String operationalState,
229             Map<String, Object> outProperties) {
230         intermediaryApi.sendAcElementInfo(automationCompositionId, elementId, useState, operationalState,
231                 outProperties);
232     }
233
234     @Override
235     public void prime(UUID compositionId, List<AutomationCompositionElementDefinition> elementDefinitionList)
236             throws PfModelException {
237         LOGGER.debug("prime call");
238
239         if (!execution(config.getPrimeTimerMs(), "Current Thread prime is Interrupted during execution {}",
240                 compositionId)) {
241             return;
242         }
243
244         if (config.isPrimeSuccess()) {
245             intermediaryApi.updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.NO_ERROR,
246                     "Primed");
247         } else {
248             intermediaryApi.updateCompositionState(compositionId, AcTypeState.COMMISSIONED, StateChangeResult.FAILED,
249                     "Prime failed!");
250         }
251     }
252
253     @Override
254     public void deprime(UUID compositionId) throws PfModelException {
255         LOGGER.debug("deprime call");
256
257         if (!execution(config.getDeprimeTimerMs(), "Current Thread deprime is Interrupted during execution {}",
258                 compositionId)) {
259             return;
260         }
261
262         if (config.isDeprimeSuccess()) {
263             intermediaryApi.updateCompositionState(compositionId, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR,
264                     "Deprimed");
265         } else {
266             intermediaryApi.updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.FAILED,
267                     "Deprime failed!");
268         }
269     }
270
271     /**
272      * Get Data List.
273      *
274      * @return the InternalDatas
275      */
276     public InternalDatas getDataList() {
277         var result = new InternalDatas();
278         var map = intermediaryApi.getAutomationCompositions();
279         for (var instance : map.values()) {
280             for (var element : instance.getElements().values()) {
281                 var data = new InternalData();
282                 data.setAutomationCompositionId(instance.getInstanceId());
283                 data.setAutomationCompositionElementId(element.getId());
284                 data.setIntProperties(element.getProperties());
285                 data.setOperationalState(element.getOperationalState());
286                 data.setUseState(element.getUseState());
287                 data.setOutProperties(element.getOutProperties());
288                 result.getList().add(data);
289             }
290         }
291         return result;
292     }
293
294     @Override
295     public void handleRestartComposition(UUID compositionId,
296             List<AutomationCompositionElementDefinition> elementDefinitionList, AcTypeState state)
297             throws PfModelException {
298         LOGGER.debug("restart composition definition call");
299         switch (state) {
300             case PRIMING:
301                 prime(compositionId, elementDefinitionList);
302                 break;
303
304             case DEPRIMING:
305                 deprime(compositionId);
306                 break;
307
308             default:
309                 intermediaryApi.updateCompositionState(compositionId, state, StateChangeResult.NO_ERROR, "Restarted");
310         }
311     }
312
313     @Override
314     public void handleRestartInstance(UUID automationCompositionId, AcElementDeploy element,
315             Map<String, Object> properties, DeployState deployState, LockState lockState) throws PfModelException {
316         LOGGER.debug("restart instance call");
317         if (!AcmUtils.isInTransitionalState(deployState, lockState)) {
318             intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(),
319                     deployState, lockState, StateChangeResult.NO_ERROR, "Restarted");
320             return;
321         }
322         if (DeployState.DEPLOYING.equals(deployState)) {
323             deploy(automationCompositionId, element, properties);
324             return;
325         }
326         if (DeployState.UNDEPLOYING.equals(deployState)) {
327             undeploy(automationCompositionId, element.getId());
328             return;
329         }
330         if (DeployState.UPDATING.equals(deployState)) {
331             update(automationCompositionId, element, properties);
332             return;
333         }
334         if (DeployState.DELETING.equals(deployState)) {
335             delete(automationCompositionId, element.getId());
336             return;
337         }
338         if (LockState.LOCKING.equals(lockState)) {
339             lock(automationCompositionId, element.getId());
340             return;
341         }
342         if (LockState.UNLOCKING.equals(lockState)) {
343             unlock(automationCompositionId, element.getId());
344         }
345     }
346 }