284aa0e5aa34d6a913d3a5e48f7c24a6340dbe01
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2024 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.util.ArrayList;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.UUID;
27 import lombok.Getter;
28 import lombok.RequiredArgsConstructor;
29 import lombok.Setter;
30 import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
31 import org.onap.policy.clamp.acm.participant.sim.model.InternalData;
32 import org.onap.policy.clamp.acm.participant.sim.model.InternalDatas;
33 import org.onap.policy.clamp.acm.participant.sim.model.SimConfig;
34 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
35 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
36 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions;
37 import org.onap.policy.clamp.models.acm.concepts.DeployState;
38 import org.onap.policy.clamp.models.acm.concepts.LockState;
39 import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils;
40 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
41 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44 import org.springframework.stereotype.Service;
45
46 /**
47  * This class handles implementation of Simulator Service.
48  */
49 @Service
50 @RequiredArgsConstructor
51 public class SimulatorService {
52
53     private final ParticipantIntermediaryApi intermediaryApi;
54
55     private static final Logger LOGGER = LoggerFactory.getLogger(SimulatorService.class);
56
57     @Getter
58     @Setter
59     private SimConfig config = new SimConfig();
60
61     /**
62      * Get AutomationComposition.
63      *
64      * @return the AutomationCompositions
65      */
66     public AutomationCompositions getAutomationCompositions() {
67         var result = new AutomationCompositions();
68         result.setAutomationCompositionList(new ArrayList<>(intermediaryApi.getAutomationCompositions().values()));
69         return result;
70     }
71
72     public AutomationComposition getAutomationComposition(UUID instanceId) {
73         return intermediaryApi.getAutomationComposition(instanceId);
74     }
75
76     /**
77      * Set OutProperties.
78      *
79      * @param instanceId the automationComposition Id
80      * @param elementId the automationComposition Element Id
81      * @param useState the useState
82      * @param operationalState the operationalState
83      * @param outProperties the outProperties
84      */
85     public void setOutProperties(UUID instanceId, UUID elementId, String useState, String operationalState,
86                                  Map<String, Object> outProperties) {
87         intermediaryApi.sendAcElementInfo(instanceId, elementId, useState, operationalState,
88                 outProperties);
89     }
90
91     /**
92      * Get Instance Data List.
93      *
94      * @return the InternalDatas
95      */
96     public InternalDatas getDataList() {
97         var result = new InternalDatas();
98         var map = intermediaryApi.getAutomationCompositions();
99         for (var instance : map.values()) {
100             for (var element : instance.getElements().values()) {
101                 var data = new InternalData();
102                 data.setCompositionId(instance.getCompositionId());
103                 data.setAutomationCompositionId(instance.getInstanceId());
104                 data.setAutomationCompositionElementId(element.getId());
105                 data.setIntProperties(element.getProperties());
106                 data.setOperationalState(element.getOperationalState());
107                 data.setUseState(element.getUseState());
108                 data.setOutProperties(element.getOutProperties());
109                 result.getList().add(data);
110             }
111         }
112         return result;
113     }
114
115     /**
116      * Get Composition Data List.
117      *
118      * @return the InternalDatas
119      */
120     public InternalDatas getCompositionDataList() {
121         var acElementsDefinitions = intermediaryApi.getAcElementsDefinitions();
122         var internalDatas = new InternalDatas();
123         for (var entry : acElementsDefinitions.entrySet()) {
124             for (var acElementsDefinition : entry.getValue().values()) {
125                 var internalData = new InternalData();
126                 internalData.setCompositionId(entry.getKey());
127                 internalData.setCompositionDefinitionElementId(acElementsDefinition.getAcElementDefinitionId());
128                 internalData.setIntProperties(
129                         acElementsDefinition.getAutomationCompositionElementToscaNodeTemplate().getProperties());
130                 internalData.setOutProperties(acElementsDefinition.getOutProperties());
131                 internalDatas.getList().add(internalData);
132             }
133         }
134         return internalDatas;
135     }
136
137     public void setCompositionOutProperties(UUID compositionId, ToscaConceptIdentifier compositionDefinitionElementId,
138                                             Map<String, Object> outProperties) {
139         intermediaryApi.sendAcDefinitionInfo(compositionId, compositionDefinitionElementId, outProperties);
140
141     }
142
143     private boolean execution(int timeMs, String msg, UUID elementId) {
144         long endTime = System.currentTimeMillis() + timeMs;
145         while (System.currentTimeMillis() < endTime) {
146             try {
147                 if (Thread.currentThread().isInterrupted()) {
148                     LOGGER.debug(msg, elementId);
149                     return false;
150                 }
151                 Thread.sleep(10L);
152             } catch (InterruptedException e) {
153                 LOGGER.debug(msg, elementId);
154                 Thread.currentThread().interrupt();
155                 return false;
156             }
157         }
158         return true;
159     }
160
161     /**
162      * Handle a deploy on a automation composition element.
163      *
164      * @param instanceId the instanceId
165      * @param elementId the elementId
166      */
167     public void deploy(UUID instanceId, UUID elementId) {
168         if (!execution(getConfig().getDeployTimerMs(),
169                 "Current Thread deploy is Interrupted during execution {}", elementId)) {
170             return;
171         }
172
173         if (getConfig().isDeploySuccess()) {
174             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
175                     DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed");
176         } else {
177             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
178                     DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Deploy failed!");
179         }
180     }
181
182     /**
183      * Handle an udeploy on a automation composition element.
184      *
185      * @param instanceId the instanceId
186      * @param elementId the elementId
187      */
188     public void undeploy(UUID instanceId, UUID elementId) {
189         if (!execution(getConfig().getUndeployTimerMs(),
190                 "Current Thread undeploy is Interrupted during execution {}", elementId)) {
191             return;
192         }
193
194         if (getConfig().isUndeploySuccess()) {
195             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
196                     DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed");
197         } else {
198             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
199                     DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Undeploy failed!");
200         }
201     }
202
203     /**
204      * Handle a lock on a automation composition element.
205      *
206      * @param instanceId the instanceId
207      * @param elementId the elementId
208      */
209     public void lock(UUID instanceId, UUID elementId) {
210         if (!execution(getConfig().getLockTimerMs(),
211                 "Current Thread lock is Interrupted during execution {}", elementId)) {
212             return;
213         }
214
215         if (getConfig().isLockSuccess()) {
216             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
217                     null, LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked");
218         } else {
219             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
220                     null, LockState.UNLOCKED, StateChangeResult.FAILED, "Lock failed!");
221         }
222     }
223
224     /**
225      * Handle an unlock on a automation composition element.
226      *
227      * @param instanceId the instanceId
228      * @param elementId the elementId
229      */
230     public void unlock(UUID instanceId, UUID elementId) {
231         if (!execution(getConfig().getUnlockTimerMs(),
232                 "Current Thread unlock is Interrupted during execution {}", elementId)) {
233             return;
234         }
235
236         if (getConfig().isUnlockSuccess()) {
237             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
238                     null, LockState.UNLOCKED, StateChangeResult.NO_ERROR, "Unlocked");
239         } else {
240             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
241                     null, LockState.LOCKED, StateChangeResult.FAILED, "Unlock failed!");
242         }
243     }
244
245     /**
246      * Handle a delete on a automation composition element.
247      *
248      * @param instanceId the instanceId
249      * @param elementId the elementId
250      */
251     public void delete(UUID instanceId, UUID elementId) {
252         if (!execution(getConfig().getDeleteTimerMs(),
253                 "Current Thread delete is Interrupted during execution {}", elementId)) {
254             return;
255         }
256
257         if (getConfig().isDeleteSuccess()) {
258             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
259                     DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted");
260         } else {
261             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
262                     DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Delete failed!");
263         }
264     }
265
266     /**
267      * Handle an update on a automation composition element.
268      *
269      * @param instanceId the instanceId
270      * @param elementId the elementId
271      */
272     public void update(UUID instanceId, UUID elementId) {
273         if (!execution(getConfig().getUpdateTimerMs(),
274                 "Current Thread update is Interrupted during execution {}", elementId)) {
275             return;
276         }
277
278         if (getConfig().isUpdateSuccess()) {
279             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
280                     DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Updated");
281         } else {
282             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
283                     DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Update failed!");
284         }
285     }
286
287     /**
288      * Handle a prime on a automation composition definition.
289      *
290      * @param compositionId the compositionId
291      */
292     public void prime(UUID compositionId) {
293         if (!execution(getConfig().getPrimeTimerMs(),
294                 "Current Thread prime is Interrupted during execution {}", compositionId)) {
295             return;
296         }
297
298         if (getConfig().isPrimeSuccess()) {
299             intermediaryApi.updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.NO_ERROR,
300                     "Primed");
301         } else {
302             intermediaryApi.updateCompositionState(compositionId, AcTypeState.COMMISSIONED, StateChangeResult.FAILED,
303                     "Prime failed!");
304         }
305     }
306
307     /**
308      * Handle a deprime on a automation composition definition.
309      *
310      * @param compositionId the compositionId
311      */
312     public void deprime(UUID compositionId) {
313         if (!execution(getConfig().getDeprimeTimerMs(),
314                 "Current Thread deprime is Interrupted during execution {}", compositionId)) {
315             return;
316         }
317
318         if (getConfig().isDeprimeSuccess()) {
319             intermediaryApi.updateCompositionState(compositionId, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR,
320                     "Deprimed");
321         } else {
322             intermediaryApi.updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.FAILED,
323                     "Deprime failed!");
324         }
325     }
326
327     /**
328      * Handle a migrate on a automation composition element.
329      *
330      * @param instanceId the instanceId
331      * @param elementId the elementId
332      * @param stage the stage
333      */
334     public void migrate(UUID instanceId, UUID elementId, int stage, Map<String, Object> compositionInProperties,
335             Map<String, Object> instanceOutProperties) {
336         if (!execution(getConfig().getMigrateTimerMs(),
337                 "Current Thread migrate is Interrupted during execution {}", elementId)) {
338             return;
339         }
340
341         if (config.isMigrateSuccess()) {
342             var stageSet = ParticipantUtils.findStageSet(compositionInProperties);
343             var nextStage = 1000;
344             for (var s : stageSet) {
345                 if (s > stage) {
346                     nextStage = Math.min(s, nextStage);
347                 }
348             }
349             instanceOutProperties.putIfAbsent("stage", new ArrayList<>());
350             @SuppressWarnings("unchecked")
351             var stageList = (List<Integer>) instanceOutProperties.get("stage");
352             stageList.add(stage);
353             intermediaryApi.sendAcElementInfo(instanceId, elementId, null, null, instanceOutProperties);
354             if (nextStage == 1000) {
355                 intermediaryApi.updateAutomationCompositionElementState(
356                         instanceId, elementId,
357                         DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated");
358             } else {
359                 intermediaryApi.updateAutomationCompositionElementStage(
360                         instanceId, elementId,
361                         StateChangeResult.NO_ERROR, nextStage, "stage " + stage + " Migrated");
362             }
363         } else {
364             intermediaryApi.updateAutomationCompositionElementState(
365                     instanceId, elementId,
366                     DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Migrate failed!");
367         }
368     }
369
370     /**
371      * Handle a Migrate Precheck on a automation composition element.
372      *
373      * @param instanceId the instanceId
374      * @param elementId the elementId
375      */
376     public void migratePrecheck(UUID instanceId, UUID elementId) {
377         if (!execution(config.getMigratePrecheckTimerMs(),
378                 "Current Thread migrate precheck is Interrupted during execution {}", elementId)) {
379             return;
380         }
381
382         if (config.isMigratePrecheck()) {
383             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
384                     DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migration precheck completed");
385         } else {
386             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
387                     DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Migration precheck failed");
388         }
389     }
390
391     /**
392      * Handle a Prepare on a automation composition element.
393      *
394      * @param instanceId the instanceId
395      * @param elementId the elementId
396      */
397     public void prepare(UUID instanceId, UUID elementId) {
398         if (!execution(config.getPrepareTimerMs(),
399                 "Current Thread prepare is Interrupted during execution {}", elementId)) {
400             return;
401         }
402
403         if (config.isPrepare()) {
404             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
405                     DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Prepare completed");
406         } else {
407             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
408                     DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Prepare failed");
409         }
410     }
411
412     /**
413      * Handle a Review on a automation composition element.
414      *
415      * @param instanceId the instanceId
416      * @param elementId the elementId
417      */
418     public void review(UUID instanceId, UUID elementId) {
419         if (!execution(config.getReviewTimerMs(),
420                 "Current Thread review is Interrupted during execution {}", elementId)) {
421             return;
422         }
423
424         if (config.isReview()) {
425             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
426                     DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Review completed");
427         } else {
428             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
429                     DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Review failed");
430         }
431     }
432 }