2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2021-2025 OpenInfra Foundation Europe. All rights reserved.
4 * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.clamp.acm.runtime.instantiation;
24 import jakarta.validation.Valid;
25 import jakarta.ws.rs.core.Response.Status;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.List;
29 import java.util.UUID;
30 import java.util.stream.Collectors;
31 import lombok.NonNull;
32 import lombok.RequiredArgsConstructor;
33 import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup;
34 import org.onap.policy.clamp.acm.runtime.main.utils.EncryptionUtils;
35 import org.onap.policy.clamp.acm.runtime.supervision.SupervisionAcHandler;
36 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
37 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
38 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
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.MigrationState;
43 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
44 import org.onap.policy.clamp.models.acm.concepts.SubState;
45 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AcInstanceStateUpdate;
46 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
47 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse;
48 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder;
49 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.SubOrder;
50 import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
51 import org.onap.policy.clamp.models.acm.persistence.provider.AcInstanceStateResolver;
52 import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
53 import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
54 import org.onap.policy.clamp.models.acm.utils.AcmStageUtils;
55 import org.onap.policy.clamp.models.acm.utils.AcmStateUtils;
56 import org.onap.policy.clamp.models.acm.utils.AcmUtils;
57 import org.onap.policy.common.parameters.BeanValidationResult;
58 import org.onap.policy.models.base.PfModelRuntimeException;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61 import org.springframework.data.domain.Pageable;
62 import org.springframework.stereotype.Service;
63 import org.springframework.transaction.annotation.Transactional;
66 * This class is dedicated to the Instantiation of Commissioned automation composition.
70 @RequiredArgsConstructor
71 public class AutomationCompositionInstantiationProvider {
72 private static final String DO_NOT_MATCH = " do not match with ";
73 private static final String ELEMENT_ID_NOT_PRESENT = "Element id not present ";
74 private static final String NOT_VALID_ORDER =
75 "Not valid order %s; DeployState: %s; LockState: %s; SubState: %s; StateChangeResult: %s";
77 private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionInstantiationProvider.class);
79 private final AutomationCompositionProvider automationCompositionProvider;
80 private final AcDefinitionProvider acDefinitionProvider;
81 private final AcInstanceStateResolver acInstanceStateResolver;
82 private final SupervisionAcHandler supervisionAcHandler;
83 private final ParticipantProvider participantProvider;
84 private final AcRuntimeParameterGroup acRuntimeParameterGroup;
85 private final EncryptionUtils encryptionUtils;
88 * Create automation composition.
90 * @param compositionId The UUID of the automation composition definition
91 * @param automationComposition the automation composition
92 * @return the result of the instantiation operation
94 public InstantiationResponse createAutomationComposition(UUID compositionId,
95 AutomationComposition automationComposition) {
96 LOGGER.info("Create instance request received for compositionId {}", compositionId);
97 AutomationCompositionProvider.validateInstanceEndpoint(compositionId, automationComposition);
98 automationCompositionProvider.validateNameVersion(automationComposition.getKey().asIdentifier());
100 var acDefinition = acDefinitionProvider.getAcDefinition(compositionId);
101 AcDefinitionProvider.checkPrimedComposition(acDefinition);
102 var validationResult = validateAutomationComposition(automationComposition, acDefinition, 0);
103 if (!validationResult.isValid()) {
104 throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
106 associateParticipantId(automationComposition, acDefinition, null);
108 encryptInstanceProperties(automationComposition, compositionId);
109 automationComposition = automationCompositionProvider.createAutomationComposition(automationComposition);
111 return createInstantiationResponse(automationComposition);
114 private InstantiationResponse createInstantiationResponse(AutomationComposition automationComposition) {
115 var response = new InstantiationResponse();
116 response.setInstanceId(automationComposition.getInstanceId());
117 response.setAffectedAutomationComposition(automationComposition.getKey().asIdentifier());
122 * Update automation composition.
124 * @param compositionId The UUID of the automation composition definition
125 * @param automationComposition the automation composition
126 * @return the result of the update
128 public InstantiationResponse updateAutomationComposition(UUID compositionId,
129 AutomationComposition automationComposition) {
130 var instanceId = automationComposition.getInstanceId();
131 var acFromDb = automationCompositionProvider.getAutomationComposition(instanceId);
132 AutomationCompositionProvider.validateInstanceEndpoint(compositionId, acFromDb);
133 var acDefinition = acDefinitionProvider.getAcDefinition(compositionId);
134 AcDefinitionProvider.checkPrimedComposition(acDefinition);
135 AcmUtils.checkMigrationState(acFromDb);
136 if (DeployState.UNDEPLOYED.equals(acFromDb.getDeployState())) {
137 LOGGER.info("Updating undeployed instance with id {}", instanceId);
138 acFromDb.setElements(automationComposition.getElements());
139 acFromDb.setName(automationComposition.getName());
140 acFromDb.setVersion(automationComposition.getVersion());
141 acFromDb.setDescription(automationComposition.getDescription());
142 acFromDb.setDerivedFrom(automationComposition.getDerivedFrom());
143 var validationResult = validateAutomationComposition(acFromDb, acDefinition, 0);
144 if (!validationResult.isValid()) {
145 throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
147 associateParticipantId(acFromDb, acDefinition, null);
149 encryptInstanceProperties(acFromDb, compositionId);
150 automationComposition = automationCompositionProvider.updateAutomationComposition(acFromDb);
151 return createInstantiationResponse(automationComposition);
155 var deployOrder = DeployOrder.UPDATE;
156 var subOrder = SubOrder.NONE;
158 if (automationComposition.getCompositionTargetId() != null) {
160 if (Boolean.TRUE.equals(automationComposition.getPrecheck())) {
161 subOrder = SubOrder.MIGRATE_PRECHECK;
162 deployOrder = DeployOrder.NONE;
164 deployOrder = DeployOrder.MIGRATE;
167 var result = acInstanceStateResolver.resolve(deployOrder, LockOrder.NONE, subOrder,
168 acFromDb.getDeployState(), acFromDb.getLockState(), acFromDb.getSubState(),
169 acFromDb.getStateChangeResult());
170 return switch (result) {
171 case "UPDATE" -> updateDeployedAutomationComposition(automationComposition, acFromDb, acDefinition);
173 case "MIGRATE" -> migrateAutomationComposition(automationComposition, acFromDb, acDefinition);
175 case "MIGRATE_PRECHECK" -> migratePrecheckAc(automationComposition, acFromDb, acDefinition);
177 default -> throw new PfModelRuntimeException(Status.BAD_REQUEST,
178 "Not allowed to " + deployOrder + " in the state " + acFromDb.getDeployState());
183 * Update deployed AC Element properties.
185 * @param automationComposition the automation composition
186 * @param acToBeUpdated the composition to be updated
187 * @return the result of the update
189 InstantiationResponse updateDeployedAutomationComposition(
190 AutomationComposition automationComposition, AutomationComposition acToBeUpdated,
191 AutomationCompositionDefinition acDefinition) {
192 // save copy in case of a rollback
193 automationCompositionProvider.copyAcElementsBeforeUpdate(acToBeUpdated);
194 LOGGER.info("Updating deployed instance with id {}", automationComposition.getInstanceId());
196 // Iterate and update the element property values
197 for (var element : automationComposition.getElements().entrySet()) {
198 var elementId = element.getKey();
199 var dbAcElement = acToBeUpdated.getElements().get(elementId);
200 if (dbAcElement == null) {
201 throw new PfModelRuntimeException(Status.BAD_REQUEST, ELEMENT_ID_NOT_PRESENT + elementId);
203 AcmUtils.recursiveMerge(dbAcElement.getProperties(), element.getValue().getProperties());
206 var validationResult = validateAutomationComposition(acToBeUpdated, acDefinition, 0);
207 if (!validationResult.isValid()) {
208 throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
210 associateParticipantId(acToBeUpdated, acDefinition, null);
212 updateAcForProperties(acToBeUpdated);
214 var acToPublish = new AutomationComposition(acToBeUpdated);
215 encryptInstanceProperties(acToBeUpdated, acToBeUpdated.getCompositionId());
217 automationComposition = automationCompositionProvider.updateAutomationComposition(acToBeUpdated);
218 // Publish property update event to the participants
219 supervisionAcHandler.update(acToPublish, acDefinition.getRevisionId());
220 return createInstantiationResponse(automationComposition);
223 private InstantiationResponse migrateAutomationComposition(
224 AutomationComposition automationComposition, AutomationComposition acFromDb,
225 AutomationCompositionDefinition acDefinition) {
226 LOGGER.info("Migrating instance with id {}", automationComposition.getInstanceId());
227 if (!DeployState.DEPLOYED.equals(acFromDb.getDeployState())) {
228 throw new PfModelRuntimeException(Status.BAD_REQUEST,
229 "Not allowed to migrate in the state " + acFromDb.getDeployState());
231 // make copy for rollback
232 automationCompositionProvider.copyAcElementsBeforeUpdate(acFromDb);
234 var acDefinitionTarget = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionTargetId());
235 AcDefinitionProvider.checkPrimedComposition(acDefinitionTarget);
236 // Iterate and update the element property values
237 updateElementsProperties(automationComposition, acFromDb, acDefinitionTarget, acDefinition);
239 updateAcForMigration(acFromDb, acDefinitionTarget, DeployState.MIGRATING);
241 var acToPublish = new AutomationComposition(acFromDb);
242 encryptInstanceProperties(acFromDb, acFromDb.getCompositionTargetId());
244 var ac = automationCompositionProvider.updateAutomationComposition(acFromDb);
246 // Publish migrate event to the participants
247 supervisionAcHandler.migrate(acToPublish, acDefinition.getRevisionId(), acDefinitionTarget.getRevisionId());
248 return createInstantiationResponse(ac);
251 private void updateAcForMigration(AutomationComposition acFromDb,
252 AutomationCompositionDefinition acDefinition, DeployState deployState) {
253 AcmStateUtils.setCascadedState(acFromDb, deployState, LockState.LOCKED);
254 acFromDb.setStateChangeResult(StateChangeResult.NO_ERROR);
255 var stage = DeployState.MIGRATION_REVERTING.equals(deployState)
256 ? AcmStageUtils.getLastStage(acFromDb, acDefinition.getServiceTemplate())
257 : AcmStageUtils.getFirstStage(acFromDb, acDefinition.getServiceTemplate());
258 acFromDb.setPhase(stage);
261 private void updateAcForProperties(AutomationComposition acToBeUpdated) {
262 AcmStateUtils.setCascadedState(acToBeUpdated, DeployState.UPDATING, acToBeUpdated.getLockState());
263 acToBeUpdated.setStateChangeResult(StateChangeResult.NO_ERROR);
266 private List<AutomationCompositionElement> getElementRemoved(AutomationComposition acFromDb,
267 AutomationComposition acFromMigration) {
268 return acFromDb.getElements().values().stream()
269 .filter(element -> acFromMigration.getElements().get(element.getId()) == null).toList();
273 private InstantiationResponse migratePrecheckAc(
274 AutomationComposition automationComposition, AutomationComposition acToBeUpdated,
275 AutomationCompositionDefinition acDefinition) {
277 acToBeUpdated.setPrecheck(true);
278 LOGGER.info("Running migrate precheck for id: {}", automationComposition.getInstanceId());
279 var copyAc = new AutomationComposition(acToBeUpdated);
280 var acDefinitionTarget = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionTargetId());
281 AcDefinitionProvider.checkPrimedComposition(acDefinitionTarget);
282 // Iterate and update the element property values
283 updateElementsProperties(automationComposition, copyAc, acDefinitionTarget, acDefinition);
285 // Publish migrate event to the participants
286 supervisionAcHandler.migratePrecheck(copyAc, acDefinition.getRevisionId(), acDefinitionTarget.getRevisionId());
288 AcmStateUtils.setCascadedState(acToBeUpdated, DeployState.DEPLOYED, LockState.LOCKED,
289 SubState.MIGRATION_PRECHECKING);
290 acToBeUpdated.setStateChangeResult(StateChangeResult.NO_ERROR);
292 return createInstantiationResponse(automationCompositionProvider.updateAutomationComposition(acToBeUpdated));
296 * Validate AutomationComposition.
298 * @param automationComposition AutomationComposition to validate
299 * @param acDefinition the Composition Definition
300 * @return the result of validation
302 private BeanValidationResult validateAutomationComposition(AutomationComposition automationComposition,
303 AutomationCompositionDefinition acDefinition, int removeElement) {
304 var result = new BeanValidationResult("AutomationComposition", automationComposition);
305 participantProvider.checkRegisteredParticipant(acDefinition);
306 result.addResult(AcmUtils.validateAutomationComposition(automationComposition,
307 acDefinition.getServiceTemplate(),
308 acRuntimeParameterGroup.getAcmParameters().getToscaCompositionName(), removeElement));
310 result.addResult(automationCompositionProvider.validateElementIds(automationComposition));
316 private void encryptInstanceProperties(AutomationComposition automationComposition, UUID compositionId) {
317 if (encryptionUtils.encryptionEnabled()) {
318 var acDefinitionOpt = acDefinitionProvider.findAcDefinition(compositionId);
319 acDefinitionOpt.ifPresent(acDefinition
320 -> encryptionUtils.findAndEncryptSensitiveData(acDefinition, automationComposition));
325 * Get Automation Composition.
327 * @param compositionId The UUID of the automation composition definition
328 * @param instanceId The UUID of the automation composition instance
329 * @return the Automation Composition
331 @Transactional(readOnly = true)
332 public AutomationComposition getAutomationComposition(@NonNull UUID compositionId, UUID instanceId) {
333 var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
334 if (!compositionId.equals(automationComposition.getCompositionId())
335 && !compositionId.equals(automationComposition.getCompositionTargetId())) {
336 throw new PfModelRuntimeException(Status.BAD_REQUEST,
337 automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
339 return automationComposition;
343 * Delete the automation composition with the given name and version.
345 * @param compositionId The UUID of the automation composition definition
346 * @param instanceId The UUID of the automation composition instance
347 * @return the result of the deletion
349 public InstantiationResponse deleteAutomationComposition(UUID compositionId, UUID instanceId) {
350 var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
351 var acDefinition = getAcDefinition(compositionId, automationComposition);
352 LOGGER.info("Delete automation composition request received for name: {} and version: {}",
353 automationComposition.getName(), automationComposition.getVersion());
354 var result = acInstanceStateResolver.resolve(DeployOrder.DELETE,
356 automationComposition.getDeployState(), automationComposition.getLockState(),
357 automationComposition.getSubState(), automationComposition.getStateChangeResult());
358 if (!DeployOrder.DELETE.name().equals(result)) {
359 var msg = String.format(NOT_VALID_ORDER, DeployOrder.DELETE,
360 automationComposition.getDeployState(), automationComposition.getLockState(),
361 automationComposition.getSubState(), automationComposition.getStateChangeResult());
362 throw new PfModelRuntimeException(Status.BAD_REQUEST, msg);
364 supervisionAcHandler.delete(automationComposition, acDefinition);
365 return createInstantiationResponse(automationComposition);
369 * Get the requested automation compositions.
371 * @param name the name of the automation composition to get, null for all automation compositions
372 * @param version the version of the automation composition to get, null for all automation compositions
373 * @param pageable the Pageable
374 * @return the automation compositions
376 @Transactional(readOnly = true)
377 public AutomationCompositions getAutomationCompositions(@NonNull final UUID compositionId,
378 final String name, final String version,
379 @NonNull final Pageable pageable) {
380 var automationCompositions = new AutomationCompositions();
381 automationCompositions.setAutomationCompositionList(
382 automationCompositionProvider.getAutomationCompositions(compositionId, name, version, pageable));
384 return automationCompositions;
388 * Handle Composition Instance State.
390 * @param compositionId the compositionId
391 * @param instanceId the instanceId
392 * @param acInstanceStateUpdate the AcInstanceStateUpdate
394 public void compositionInstanceState(UUID compositionId, UUID instanceId,
395 @Valid AcInstanceStateUpdate acInstanceStateUpdate) {
396 var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
397 var acDefinition = getAcDefinition(compositionId, automationComposition);
398 var result = acInstanceStateResolver.resolve(acInstanceStateUpdate.getDeployOrder(),
399 acInstanceStateUpdate.getLockOrder(), acInstanceStateUpdate.getSubOrder(),
400 automationComposition.getDeployState(), automationComposition.getLockState(),
401 automationComposition.getSubState(), automationComposition.getStateChangeResult());
404 supervisionAcHandler.deploy(automationComposition, acDefinition);
408 supervisionAcHandler.undeploy(automationComposition, acDefinition);
412 supervisionAcHandler.lock(automationComposition, acDefinition);
416 supervisionAcHandler.unlock(automationComposition, acDefinition);
420 supervisionAcHandler.prepare(automationComposition, acDefinition);
424 supervisionAcHandler.review(automationComposition, acDefinition);
428 var msg = String.format(NOT_VALID_ORDER, acInstanceStateUpdate,
429 automationComposition.getDeployState(), automationComposition.getLockState(),
430 automationComposition.getSubState(), automationComposition.getStateChangeResult());
431 throw new PfModelRuntimeException(Status.BAD_REQUEST, msg);
436 * Rollback AC Instance.
438 * @param compositionId The UUID of the automation composition definition
439 * @param instanceId The UUID of the automation composition instance
441 public void rollback(UUID compositionId, UUID instanceId) {
442 LOGGER.info("Rollback automation composition request received for CompositionID: {} and InstanceID: {}",
443 compositionId, instanceId);
444 var acFromDb = automationCompositionProvider.getAutomationComposition(instanceId);
445 AutomationCompositionProvider.validateInstanceEndpoint(compositionId, acFromDb);
447 if (!DeployOrder.MIGRATION_REVERT.name().equals(acInstanceStateResolver.resolve(
448 DeployOrder.MIGRATION_REVERT, LockOrder.NONE,
449 SubOrder.NONE, acFromDb.getDeployState(), acFromDb.getLockState(),
450 acFromDb.getSubState(), acFromDb.getStateChangeResult()))) {
451 throw new PfModelRuntimeException(Status.BAD_REQUEST, "Invalid state for rollback");
454 var automationCompositionToRollback =
455 automationCompositionProvider.getAutomationCompositionRollback(instanceId);
456 var acFromDbCopy = new AutomationComposition(acFromDb);
457 acFromDbCopy.setElements(automationCompositionToRollback.getElements().values().stream()
458 .collect(Collectors.toMap(AutomationCompositionElement::getId, AutomationCompositionElement::new)));
460 var acDefinition = acDefinitionProvider.getAcDefinition(acFromDbCopy.getCompositionId());
461 var validationResult = validateAutomationComposition(acFromDbCopy, acDefinition, 0);
462 if (!validationResult.isValid()) {
463 throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
465 // Include new elements from migration for the participant undeploy
466 for (var element : acFromDb.getElements().values()) {
467 if (MigrationState.NEW.equals(element.getMigrationState())) {
468 acFromDbCopy.getElements().put(element.getId(), element);
470 if (MigrationState.REMOVED.equals(element.getMigrationState())) {
471 acFromDbCopy.getElements().get(element.getId()).setMigrationState(MigrationState.REMOVED);
475 updateAcForMigration(acFromDbCopy, acDefinition, DeployState.MIGRATION_REVERTING);
476 automationCompositionProvider.updateAutomationComposition(acFromDbCopy);
477 var acDefinitionTarget = acDefinitionProvider.getAcDefinition(acFromDbCopy.getCompositionTargetId());
478 supervisionAcHandler.migrate(acFromDbCopy, acDefinition.getRevisionId(), acDefinitionTarget.getRevisionId());
481 private void updateElementsProperties(AutomationComposition automationComposition,
482 AutomationComposition acFromDb, AutomationCompositionDefinition acDefinitionTarget,
483 AutomationCompositionDefinition acDefinition) {
484 for (var element : automationComposition.getElements().entrySet()) {
485 var elementId = element.getKey();
486 var dbAcElement = acFromDb.getElements().get(elementId);
487 if (dbAcElement == null) {
488 LOGGER.info("New Ac element {} added in Migration", elementId);
489 element.getValue().setMigrationState(MigrationState.NEW);
490 acFromDb.getElements().put(elementId, element.getValue());
492 AcmUtils.recursiveMerge(dbAcElement.getProperties(), element.getValue().getProperties());
493 var newDefinition = element.getValue().getDefinition().asConceptKey();
494 var dbElementDefinition = dbAcElement.getDefinition().asConceptKey();
495 AutomationCompositionProvider.checkCompatibility(
496 newDefinition, dbElementDefinition, automationComposition.getInstanceId());
497 dbAcElement.setDefinition(element.getValue().getDefinition());
500 // Update migrationState for the removed elements
501 var elementsRemoved = getElementRemoved(acFromDb, automationComposition);
502 elementsRemoved.forEach(element -> acFromDb.getElements().get(element.getId())
503 .setMigrationState(MigrationState.REMOVED));
505 var validationResult = validateAutomationComposition(acFromDb, acDefinitionTarget, elementsRemoved.size());
506 if (!validationResult.isValid()) {
507 throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
509 associateParticipantId(acFromDb, acDefinitionTarget, acDefinition);
511 acFromDb.setCompositionTargetId(automationComposition.getCompositionTargetId());
514 private void associateParticipantId(AutomationComposition acFromDb,
515 AutomationCompositionDefinition acDefinitionTarget,
516 AutomationCompositionDefinition oldAcDefinition) {
517 for (var element : acFromDb.getElements().values()) {
518 var name = element.getDefinition().getName();
519 var migrationState = element.getMigrationState();
520 if (MigrationState.DEFAULT.equals(migrationState) || MigrationState.NEW.equals(migrationState)) {
521 var participantId = acDefinitionTarget.getElementStateMap().get(name).getParticipantId();
522 element.setParticipantId(participantId);
523 } else if (MigrationState.REMOVED.equals(migrationState) && oldAcDefinition != null) {
524 var participantId = oldAcDefinition.getElementStateMap().get(name).getParticipantId();
525 element.setParticipantId(participantId);
530 private AutomationCompositionDefinition getAcDefinition(UUID compositionId,
531 AutomationComposition automationComposition) {
532 AutomationCompositionProvider.validateInstanceEndpoint(compositionId, automationComposition);
533 var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId());
534 participantProvider.checkRegisteredParticipant(acDefinition);
539 * Retrieves a list of AutomationComposition instances filtered by the specified state change results
540 * and deployment states. The result can be paginated and sorted based on the provided parameters.
542 * @param instanceIds a list of instance UUIDs
543 * @param stateChangeResults a list of StateChangeResult values to filter the AutomationComposition instances
544 * @param deployStates a list of DeployState values to filter the AutomationComposition instances
545 * @param pageable the pagination information including page size and page number
546 * @return a list of AutomationComposition instances that match the specified filters
548 public AutomationCompositions getAcInstancesByFilter(
549 final String instanceIds, final String stateChangeResults, final String deployStates,
550 final Pageable pageable) {
552 LOGGER.info("Get automation compositions request received with filters");
553 List<String> acIds = new ArrayList<>();
554 if (instanceIds != null) {
555 Arrays.stream(instanceIds.split(",")).forEach(acId -> acIds.add(acId.trim()));
558 List<StateChangeResult> stateChangeResultList = new ArrayList<>();
559 if (stateChangeResults != null) {
560 Arrays.stream(stateChangeResults.split(","))
561 .forEach(stateChangeResult -> stateChangeResultList.add(StateChangeResult.valueOf(stateChangeResult)));
564 List<DeployState> deployStateList = new ArrayList<>();
565 if (deployStates != null) {
566 Arrays.stream(deployStates.split(","))
567 .forEach(deployState -> deployStateList.add(DeployState.valueOf(deployState)));
570 var instances = automationCompositionProvider.getAcInstancesByFilter(acIds, stateChangeResultList,
571 deployStateList, pageable);
572 return new AutomationCompositions(instances);