2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2024-2025 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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.clamp.acm.participant.sim.main.handler;
23 import java.util.ArrayList;
24 import java.util.List;
26 import java.util.UUID;
28 import lombok.RequiredArgsConstructor;
30 import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto;
31 import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
32 import org.onap.policy.clamp.acm.participant.sim.model.InternalData;
33 import org.onap.policy.clamp.acm.participant.sim.model.InternalDatas;
34 import org.onap.policy.clamp.acm.participant.sim.model.SimConfig;
35 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
36 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
37 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions;
38 import org.onap.policy.clamp.models.acm.concepts.DeployState;
39 import org.onap.policy.clamp.models.acm.concepts.LockState;
40 import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils;
41 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
42 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45 import org.springframework.stereotype.Service;
48 * This class handles implementation of Simulator Service.
51 @RequiredArgsConstructor
52 public class SimulatorService {
54 private final ParticipantIntermediaryApi intermediaryApi;
56 private static final Logger LOGGER = LoggerFactory.getLogger(SimulatorService.class);
57 private static final String INTERNAL_STATE = "InternalState";
61 private SimConfig config = new SimConfig();
64 * Get AutomationComposition.
66 * @return the AutomationCompositions
68 public AutomationCompositions getAutomationCompositions() {
69 var result = new AutomationCompositions();
70 result.setAutomationCompositionList(new ArrayList<>(intermediaryApi.getAutomationCompositions().values()));
74 public AutomationComposition getAutomationComposition(UUID instanceId) {
75 return intermediaryApi.getAutomationComposition(instanceId);
81 * @param instanceId the automationComposition Id
82 * @param elementId the automationComposition Element Id
83 * @param useState the useState
84 * @param operationalState the operationalState
85 * @param outProperties the outProperties
87 public void setOutProperties(UUID instanceId, UUID elementId, String useState, String operationalState,
88 Map<String, Object> outProperties) {
89 intermediaryApi.sendAcElementInfo(instanceId, elementId, useState, operationalState,
94 * Get Instance Data List.
96 * @return the InternalDatas
98 public InternalDatas getDataList() {
99 var result = new InternalDatas();
100 var map = intermediaryApi.getAutomationCompositions();
101 for (var instance : map.values()) {
102 for (var element : instance.getElements().values()) {
103 var data = new InternalData();
104 data.setCompositionId(instance.getCompositionId());
105 data.setAutomationCompositionId(instance.getInstanceId());
106 data.setAutomationCompositionElementId(element.getId());
107 data.setIntProperties(element.getProperties());
108 data.setOperationalState(element.getOperationalState());
109 data.setUseState(element.getUseState());
110 data.setOutProperties(element.getOutProperties());
111 result.getList().add(data);
118 * Get Composition Data List.
120 * @return the InternalDatas
122 public InternalDatas getCompositionDataList() {
123 var acElementsDefinitions = intermediaryApi.getAcElementsDefinitions();
124 var internalDatas = new InternalDatas();
125 for (var entry : acElementsDefinitions.entrySet()) {
126 for (var acElementsDefinition : entry.getValue().values()) {
127 var internalData = new InternalData();
128 internalData.setCompositionId(entry.getKey());
129 internalData.setCompositionDefinitionElementId(acElementsDefinition.getAcElementDefinitionId());
130 internalData.setIntProperties(
131 acElementsDefinition.getAutomationCompositionElementToscaNodeTemplate().getProperties());
132 internalData.setOutProperties(acElementsDefinition.getOutProperties());
133 internalDatas.getList().add(internalData);
136 return internalDatas;
139 public void setCompositionOutProperties(UUID compositionId, ToscaConceptIdentifier compositionDefinitionElementId,
140 Map<String, Object> outProperties) {
141 intermediaryApi.sendAcDefinitionInfo(compositionId, compositionDefinitionElementId, outProperties);
145 protected boolean execution(int timeMs, String msg, UUID elementId) {
146 long endTime = System.currentTimeMillis() + timeMs;
147 while (System.currentTimeMillis() < endTime) {
149 if (Thread.currentThread().isInterrupted()) {
150 LOGGER.debug(msg, elementId);
154 } catch (InterruptedException e) {
155 LOGGER.debug(msg, elementId);
156 Thread.currentThread().interrupt();
164 * Handle a deploy on a automation composition element.
166 * @param instanceId the instanceId
167 * @param elementId the elementId
168 * @param outProperties the outProperties
170 public void deploy(UUID instanceId, UUID elementId, Map<String, Object> outProperties) {
171 if (!execution(getConfig().getDeployTimerMs(),
172 "Current Thread deploy is Interrupted during execution {}", elementId)) {
176 if (getConfig().isDeploySuccess()) {
177 outProperties.put(INTERNAL_STATE, DeployState.DEPLOYED.name());
178 intermediaryApi.sendAcElementInfo(instanceId, elementId, null, null, outProperties);
180 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
181 DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed");
183 outProperties.put(INTERNAL_STATE, DeployState.UNDEPLOYED.name());
184 intermediaryApi.sendAcElementInfo(instanceId, elementId, null, null, outProperties);
186 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
187 DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Deploy failed!");
192 * Handle an udeploy on a automation composition element.
194 * @param instanceId the instanceId
195 * @param elementId the elementId
196 * @param outProperties the outProperties
198 public void undeploy(UUID instanceId, UUID elementId, Map<String, Object> outProperties) {
199 if (!execution(getConfig().getUndeployTimerMs(),
200 "Current Thread undeploy is Interrupted during execution {}", elementId)) {
204 if (getConfig().isUndeploySuccess()) {
205 outProperties.put(INTERNAL_STATE, DeployState.UNDEPLOYED.name());
206 intermediaryApi.sendAcElementInfo(instanceId, elementId, null, null, outProperties);
208 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
209 DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed");
211 outProperties.put(INTERNAL_STATE, DeployState.DEPLOYED.name());
212 intermediaryApi.sendAcElementInfo(instanceId, elementId, null, null, outProperties);
214 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
215 DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Undeploy failed!");
220 * Handle a lock on a automation composition element.
222 * @param instanceId the instanceId
223 * @param elementId the elementId
225 public void lock(UUID instanceId, UUID elementId) {
226 if (!execution(getConfig().getLockTimerMs(),
227 "Current Thread lock is Interrupted during execution {}", elementId)) {
231 if (getConfig().isLockSuccess()) {
232 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
233 null, LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked");
235 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
236 null, LockState.UNLOCKED, StateChangeResult.FAILED, "Lock failed!");
241 * Handle an unlock on a automation composition element.
243 * @param instanceId the instanceId
244 * @param elementId the elementId
246 public void unlock(UUID instanceId, UUID elementId) {
247 if (!execution(getConfig().getUnlockTimerMs(),
248 "Current Thread unlock is Interrupted during execution {}", elementId)) {
252 if (getConfig().isUnlockSuccess()) {
253 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
254 null, LockState.UNLOCKED, StateChangeResult.NO_ERROR, "Unlocked");
256 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
257 null, LockState.LOCKED, StateChangeResult.FAILED, "Unlock failed!");
262 * Handle a delete on a automation composition element.
264 * @param instanceId the instanceId
265 * @param elementId the elementId
267 public void delete(UUID instanceId, UUID elementId) {
268 if (!execution(getConfig().getDeleteTimerMs(),
269 "Current Thread delete is Interrupted during execution {}", elementId)) {
273 if (getConfig().isDeleteSuccess()) {
274 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
275 DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted");
277 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
278 DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Delete failed!");
283 * Handle an update on a automation composition element.
285 * @param instanceId the instanceId
286 * @param elementId the elementId
288 public void update(UUID instanceId, UUID elementId) {
289 if (!execution(getConfig().getUpdateTimerMs(),
290 "Current Thread update is Interrupted during execution {}", elementId)) {
294 if (getConfig().isUpdateSuccess()) {
295 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
296 DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Updated");
298 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
299 DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Update failed!");
304 * Handle a prime on a automation composition definition.
306 * @param composition the information of the Automation Composition Definition
308 public void prime(CompositionDto composition) {
309 if (!execution(getConfig().getPrimeTimerMs(),
310 "Current Thread prime is Interrupted during execution {}", composition.compositionId())) {
314 if (getConfig().isPrimeSuccess()) {
315 sendOutProperties(composition, AcTypeState.PRIMED.name());
316 intermediaryApi.updateCompositionState(composition.compositionId(), AcTypeState.PRIMED,
317 StateChangeResult.NO_ERROR, "Primed");
319 sendOutProperties(composition, AcTypeState.COMMISSIONED.name());
320 intermediaryApi.updateCompositionState(composition.compositionId(), AcTypeState.COMMISSIONED,
321 StateChangeResult.FAILED, "Prime failed!");
325 private void sendOutProperties(CompositionDto composition, String data) {
326 for (var elementEntry : composition.outPropertiesMap().entrySet()) {
327 elementEntry.getValue().put(INTERNAL_STATE, data);
328 intermediaryApi.sendAcDefinitionInfo(
329 composition.compositionId(), elementEntry.getKey(), elementEntry.getValue());
334 * Handle a deprime on a automation composition definition.
336 * @param composition the information of the Automation Composition Definition
338 public void deprime(CompositionDto composition) {
339 if (!execution(getConfig().getDeprimeTimerMs(),
340 "Current Thread deprime is Interrupted during execution {}", composition.compositionId())) {
344 if (getConfig().isDeprimeSuccess()) {
345 sendOutProperties(composition, AcTypeState.COMMISSIONED.name());
346 intermediaryApi.updateCompositionState(composition.compositionId(), AcTypeState.COMMISSIONED,
347 StateChangeResult.NO_ERROR, "Deprimed");
349 sendOutProperties(composition, AcTypeState.PRIMED.name());
350 intermediaryApi.updateCompositionState(composition.compositionId(), AcTypeState.PRIMED,
351 StateChangeResult.FAILED, "Deprime failed!");
356 * Handle a migrate on a automation composition element.
358 * @param instanceId the instanceId
359 * @param elementId the elementId
360 * @param stage the stage
362 public void migrate(UUID instanceId, UUID elementId, int stage, Map<String, Object> compositionInProperties,
363 Map<String, Object> instanceOutProperties) {
364 if (!execution(getConfig().getMigrateTimerMs(),
365 "Current Thread migrate is Interrupted during execution {}", elementId)) {
369 if (config.isMigrateSuccess()) {
370 var stageSet = ParticipantUtils.findStageSet(compositionInProperties);
371 var nextStage = 1000;
372 for (var s : stageSet) {
374 nextStage = Math.min(s, nextStage);
377 instanceOutProperties.putIfAbsent("stage", new ArrayList<>());
378 @SuppressWarnings("unchecked")
379 var stageList = (List<Integer>) instanceOutProperties.get("stage");
380 stageList.add(stage);
381 intermediaryApi.sendAcElementInfo(instanceId, elementId, null, null, instanceOutProperties);
382 if (nextStage == 1000) {
383 intermediaryApi.updateAutomationCompositionElementState(
384 instanceId, elementId,
385 DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated");
387 intermediaryApi.updateAutomationCompositionElementStage(
388 instanceId, elementId,
389 StateChangeResult.NO_ERROR, nextStage, "stage " + stage + " Migrated");
392 intermediaryApi.updateAutomationCompositionElementState(
393 instanceId, elementId,
394 DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Migrate failed!");
399 * Handle a Migrate Precheck on a automation composition element.
401 * @param instanceId the instanceId
402 * @param elementId the elementId
404 public void migratePrecheck(UUID instanceId, UUID elementId) {
405 if (!execution(config.getMigratePrecheckTimerMs(),
406 "Current Thread migrate precheck is Interrupted during execution {}", elementId)) {
410 if (config.isMigratePrecheck()) {
411 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
412 DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migration precheck completed");
414 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
415 DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Migration precheck failed");
420 * Handle a Prepare on a automation composition element.
422 * @param instanceId the instanceId
423 * @param elementId the elementId
425 public void prepare(UUID instanceId, UUID elementId) {
426 if (!execution(config.getPrepareTimerMs(),
427 "Current Thread prepare is Interrupted during execution {}", elementId)) {
431 if (config.isPrepare()) {
432 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
433 DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Prepare completed");
435 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
436 DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Prepare failed");
441 * Handle a Review on a automation composition element.
443 * @param instanceId the instanceId
444 * @param elementId the elementId
446 public void review(UUID instanceId, UUID elementId) {
447 if (!execution(config.getReviewTimerMs(),
448 "Current Thread review is Interrupted during execution {}", elementId)) {
452 if (config.isReview()) {
453 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
454 DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Review completed");
456 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
457 DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Review failed");