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 if (DeployState.UNDEPLOYED.equals(acFromDb.getDeployState())) {
136 LOGGER.info("Updating undeployed instance with id {}", instanceId);
137 acFromDb.setElements(automationComposition.getElements());
138 acFromDb.setName(automationComposition.getName());
139 acFromDb.setVersion(automationComposition.getVersion());
140 acFromDb.setDescription(automationComposition.getDescription());
141 acFromDb.setDerivedFrom(automationComposition.getDerivedFrom());
142 var validationResult = validateAutomationComposition(acFromDb, acDefinition, 0);
143 if (!validationResult.isValid()) {
144 throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
146 associateParticipantId(acFromDb, acDefinition, null);
148 encryptInstanceProperties(acFromDb, compositionId);
149 automationComposition = automationCompositionProvider.updateAutomationComposition(acFromDb);
150 return createInstantiationResponse(automationComposition);
154 var deployOrder = DeployOrder.UPDATE;
155 var subOrder = SubOrder.NONE;
157 if (automationComposition.getCompositionTargetId() != null) {
159 if (Boolean.TRUE.equals(automationComposition.getPrecheck())) {
160 subOrder = SubOrder.MIGRATE_PRECHECK;
161 deployOrder = DeployOrder.NONE;
163 deployOrder = DeployOrder.MIGRATE;
166 var result = acInstanceStateResolver.resolve(deployOrder, LockOrder.NONE, subOrder,
167 acFromDb.getDeployState(), acFromDb.getLockState(), acFromDb.getSubState(),
168 acFromDb.getStateChangeResult());
169 return switch (result) {
170 case "UPDATE" -> updateDeployedAutomationComposition(automationComposition, acFromDb, acDefinition);
172 case "MIGRATE" -> migrateAutomationComposition(automationComposition, acFromDb, acDefinition);
174 case "MIGRATE_PRECHECK" -> migratePrecheckAc(automationComposition, acFromDb, acDefinition);
176 default -> throw new PfModelRuntimeException(Status.BAD_REQUEST,
177 "Not allowed to " + deployOrder + " in the state " + acFromDb.getDeployState());
182 * Update deployed AC Element properties.
184 * @param automationComposition the automation composition
185 * @param acToBeUpdated the composition to be updated
186 * @return the result of the update
188 InstantiationResponse updateDeployedAutomationComposition(
189 AutomationComposition automationComposition, AutomationComposition acToBeUpdated,
190 AutomationCompositionDefinition acDefinition) {
191 // save copy in case of a rollback
192 automationCompositionProvider.copyAcElementsBeforeUpdate(acToBeUpdated);
193 LOGGER.info("Updating deployed instance with id {}", automationComposition.getInstanceId());
195 // Iterate and update the element property values
196 for (var element : automationComposition.getElements().entrySet()) {
197 var elementId = element.getKey();
198 var dbAcElement = acToBeUpdated.getElements().get(elementId);
199 if (dbAcElement == null) {
200 throw new PfModelRuntimeException(Status.BAD_REQUEST, ELEMENT_ID_NOT_PRESENT + elementId);
202 AcmUtils.recursiveMerge(dbAcElement.getProperties(), element.getValue().getProperties());
205 var validationResult = validateAutomationComposition(acToBeUpdated, acDefinition, 0);
206 if (!validationResult.isValid()) {
207 throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
209 associateParticipantId(acToBeUpdated, acDefinition, null);
211 updateAcForProperties(acToBeUpdated);
213 var acToPublish = new AutomationComposition(acToBeUpdated);
214 encryptInstanceProperties(acToBeUpdated, acToBeUpdated.getCompositionId());
216 automationComposition = automationCompositionProvider.updateAutomationComposition(acToBeUpdated);
217 // Publish property update event to the participants
218 supervisionAcHandler.update(acToPublish, acDefinition.getRevisionId());
219 return createInstantiationResponse(automationComposition);
222 private InstantiationResponse migrateAutomationComposition(
223 AutomationComposition automationComposition, AutomationComposition acFromDb,
224 AutomationCompositionDefinition acDefinition) {
225 LOGGER.info("Migrating instance with id {}", automationComposition.getInstanceId());
226 if (!DeployState.DEPLOYED.equals(acFromDb.getDeployState())) {
227 throw new PfModelRuntimeException(Status.BAD_REQUEST,
228 "Not allowed to migrate in the state " + acFromDb.getDeployState());
230 // make copy for rollback
231 automationCompositionProvider.copyAcElementsBeforeUpdate(acFromDb);
233 var acDefinitionTarget = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionTargetId());
234 AcDefinitionProvider.checkPrimedComposition(acDefinitionTarget);
235 // Iterate and update the element property values
236 updateElementsProperties(automationComposition, acFromDb, acDefinitionTarget, acDefinition);
238 updateAcForMigration(acFromDb, acDefinitionTarget, DeployState.MIGRATING);
240 var acToPublish = new AutomationComposition(acFromDb);
241 encryptInstanceProperties(acFromDb, acFromDb.getCompositionTargetId());
243 var ac = automationCompositionProvider.updateAutomationComposition(acFromDb);
245 // Publish migrate event to the participants
246 supervisionAcHandler.migrate(acToPublish, acDefinition.getRevisionId(), acDefinitionTarget.getRevisionId());
247 return createInstantiationResponse(ac);
250 private void updateAcForMigration(AutomationComposition acFromDb,
251 AutomationCompositionDefinition acDefinition, DeployState deployState) {
252 AcmStateUtils.setCascadedState(acFromDb, deployState, LockState.LOCKED);
253 acFromDb.setStateChangeResult(StateChangeResult.NO_ERROR);
254 var stage = DeployState.MIGRATION_REVERTING.equals(deployState)
255 ? AcmStageUtils.getLastStage(acFromDb, acDefinition.getServiceTemplate())
256 : AcmStageUtils.getFirstStage(acFromDb, acDefinition.getServiceTemplate());
257 acFromDb.setPhase(stage);
260 private void updateAcForProperties(AutomationComposition acToBeUpdated) {
261 AcmStateUtils.setCascadedState(acToBeUpdated, DeployState.UPDATING, acToBeUpdated.getLockState());
262 acToBeUpdated.setStateChangeResult(StateChangeResult.NO_ERROR);
265 private List<AutomationCompositionElement> getElementRemoved(AutomationComposition acFromDb,
266 AutomationComposition acFromMigration) {
267 return acFromDb.getElements().values().stream()
268 .filter(element -> acFromMigration.getElements().get(element.getId()) == null).toList();
272 private InstantiationResponse migratePrecheckAc(
273 AutomationComposition automationComposition, AutomationComposition acToBeUpdated,
274 AutomationCompositionDefinition acDefinition) {
276 acToBeUpdated.setPrecheck(true);
277 LOGGER.info("Running migrate precheck for id: {}", automationComposition.getInstanceId());
278 var copyAc = new AutomationComposition(acToBeUpdated);
279 var acDefinitionTarget = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionTargetId());
280 AcDefinitionProvider.checkPrimedComposition(acDefinitionTarget);
281 // Iterate and update the element property values
282 updateElementsProperties(automationComposition, copyAc, acDefinitionTarget, acDefinition);
284 // Publish migrate event to the participants
285 supervisionAcHandler.migratePrecheck(copyAc, acDefinition.getRevisionId(), acDefinitionTarget.getRevisionId());
287 AcmStateUtils.setCascadedState(acToBeUpdated, DeployState.DEPLOYED, LockState.LOCKED,
288 SubState.MIGRATION_PRECHECKING);
289 acToBeUpdated.setStateChangeResult(StateChangeResult.NO_ERROR);
291 return createInstantiationResponse(automationCompositionProvider.updateAutomationComposition(acToBeUpdated));
295 * Validate AutomationComposition.
297 * @param automationComposition AutomationComposition to validate
298 * @param acDefinition the Composition Definition
299 * @return the result of validation
301 private BeanValidationResult validateAutomationComposition(AutomationComposition automationComposition,
302 AutomationCompositionDefinition acDefinition, int removeElement) {
303 var result = new BeanValidationResult("AutomationComposition", automationComposition);
304 participantProvider.checkRegisteredParticipant(acDefinition);
305 result.addResult(AcmUtils.validateAutomationComposition(automationComposition,
306 acDefinition.getServiceTemplate(),
307 acRuntimeParameterGroup.getAcmParameters().getToscaCompositionName(), removeElement));
309 result.addResult(automationCompositionProvider.validateElementIds(automationComposition));
315 private void encryptInstanceProperties(AutomationComposition automationComposition, UUID compositionId) {
316 if (encryptionUtils.encryptionEnabled()) {
317 var acDefinitionOpt = acDefinitionProvider.findAcDefinition(compositionId);
318 acDefinitionOpt.ifPresent(acDefinition
319 -> encryptionUtils.findAndEncryptSensitiveData(acDefinition, automationComposition));
324 * Get Automation Composition.
326 * @param compositionId The UUID of the automation composition definition
327 * @param instanceId The UUID of the automation composition instance
328 * @return the Automation Composition
330 @Transactional(readOnly = true)
331 public AutomationComposition getAutomationComposition(@NonNull UUID compositionId, UUID instanceId) {
332 var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
333 if (!compositionId.equals(automationComposition.getCompositionId())
334 && !compositionId.equals(automationComposition.getCompositionTargetId())) {
335 throw new PfModelRuntimeException(Status.BAD_REQUEST,
336 automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
338 return automationComposition;
342 * Delete the automation composition with the given name and version.
344 * @param compositionId The UUID of the automation composition definition
345 * @param instanceId The UUID of the automation composition instance
346 * @return the result of the deletion
348 public InstantiationResponse deleteAutomationComposition(UUID compositionId, UUID instanceId) {
349 var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
350 var acDefinition = getAcDefinition(compositionId, automationComposition);
351 LOGGER.info("Delete automation composition request received for name: {} and version: {}",
352 automationComposition.getName(), automationComposition.getVersion());
353 var result = acInstanceStateResolver.resolve(DeployOrder.DELETE,
355 automationComposition.getDeployState(), automationComposition.getLockState(),
356 automationComposition.getSubState(), automationComposition.getStateChangeResult());
357 if (!DeployOrder.DELETE.name().equals(result)) {
358 var msg = String.format(NOT_VALID_ORDER, DeployOrder.DELETE,
359 automationComposition.getDeployState(), automationComposition.getLockState(),
360 automationComposition.getSubState(), automationComposition.getStateChangeResult());
361 throw new PfModelRuntimeException(Status.BAD_REQUEST, msg);
363 supervisionAcHandler.delete(automationComposition, acDefinition);
364 return createInstantiationResponse(automationComposition);
368 * Get the requested automation compositions.
370 * @param name the name of the automation composition to get, null for all automation compositions
371 * @param version the version of the automation composition to get, null for all automation compositions
372 * @param pageable the Pageable
373 * @return the automation compositions
375 @Transactional(readOnly = true)
376 public AutomationCompositions getAutomationCompositions(@NonNull final UUID compositionId,
377 final String name, final String version,
378 @NonNull final Pageable pageable) {
379 var automationCompositions = new AutomationCompositions();
380 automationCompositions.setAutomationCompositionList(
381 automationCompositionProvider.getAutomationCompositions(compositionId, name, version, pageable));
383 return automationCompositions;
387 * Handle Composition Instance State.
389 * @param compositionId the compositionId
390 * @param instanceId the instanceId
391 * @param acInstanceStateUpdate the AcInstanceStateUpdate
393 public void compositionInstanceState(UUID compositionId, UUID instanceId,
394 @Valid AcInstanceStateUpdate acInstanceStateUpdate) {
395 var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
396 var acDefinition = getAcDefinition(compositionId, automationComposition);
397 var result = acInstanceStateResolver.resolve(acInstanceStateUpdate.getDeployOrder(),
398 acInstanceStateUpdate.getLockOrder(), acInstanceStateUpdate.getSubOrder(),
399 automationComposition.getDeployState(), automationComposition.getLockState(),
400 automationComposition.getSubState(), automationComposition.getStateChangeResult());
403 supervisionAcHandler.deploy(automationComposition, acDefinition);
407 supervisionAcHandler.undeploy(automationComposition, acDefinition);
411 supervisionAcHandler.lock(automationComposition, acDefinition);
415 supervisionAcHandler.unlock(automationComposition, acDefinition);
419 supervisionAcHandler.prepare(automationComposition, acDefinition);
423 supervisionAcHandler.review(automationComposition, acDefinition);
427 var msg = String.format(NOT_VALID_ORDER, acInstanceStateUpdate,
428 automationComposition.getDeployState(), automationComposition.getLockState(),
429 automationComposition.getSubState(), automationComposition.getStateChangeResult());
430 throw new PfModelRuntimeException(Status.BAD_REQUEST, msg);
435 * Rollback AC Instance.
437 * @param compositionId The UUID of the automation composition definition
438 * @param instanceId The UUID of the automation composition instance
440 public void rollback(UUID compositionId, UUID instanceId) {
441 LOGGER.info("Rollback automation composition request received for CompositionID: {} and InstanceID: {}",
442 compositionId, instanceId);
443 var acFromDb = automationCompositionProvider.getAutomationComposition(instanceId);
444 AutomationCompositionProvider.validateInstanceEndpoint(compositionId, acFromDb);
446 if (!DeployOrder.MIGRATION_REVERT.name().equals(acInstanceStateResolver.resolve(
447 DeployOrder.MIGRATION_REVERT, LockOrder.NONE,
448 SubOrder.NONE, acFromDb.getDeployState(), acFromDb.getLockState(),
449 acFromDb.getSubState(), acFromDb.getStateChangeResult()))) {
450 throw new PfModelRuntimeException(Status.BAD_REQUEST, "Invalid state for rollback");
453 var automationCompositionToRollback =
454 automationCompositionProvider.getAutomationCompositionRollback(instanceId);
455 var acFromDbCopy = new AutomationComposition(acFromDb);
456 acFromDbCopy.setElements(automationCompositionToRollback.getElements().values().stream()
457 .collect(Collectors.toMap(AutomationCompositionElement::getId, AutomationCompositionElement::new)));
459 var acDefinition = acDefinitionProvider.getAcDefinition(acFromDbCopy.getCompositionId());
460 var validationResult = validateAutomationComposition(acFromDbCopy, acDefinition, 0);
461 if (!validationResult.isValid()) {
462 throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
464 // Include new elements from migration for the participant undeploy
465 for (var element : acFromDb.getElements().values()) {
466 if (MigrationState.NEW.equals(element.getMigrationState())) {
467 acFromDbCopy.getElements().put(element.getId(), element);
469 if (MigrationState.REMOVED.equals(element.getMigrationState())) {
470 acFromDbCopy.getElements().get(element.getId()).setMigrationState(MigrationState.REMOVED);
474 updateAcForMigration(acFromDbCopy, acDefinition, DeployState.MIGRATION_REVERTING);
475 automationCompositionProvider.updateAutomationComposition(acFromDbCopy);
476 var acDefinitionTarget = acDefinitionProvider.getAcDefinition(acFromDbCopy.getCompositionTargetId());
477 supervisionAcHandler.migrate(acFromDbCopy, acDefinition.getRevisionId(), acDefinitionTarget.getRevisionId());
480 private void updateElementsProperties(AutomationComposition automationComposition,
481 AutomationComposition acFromDb, AutomationCompositionDefinition acDefinitionTarget,
482 AutomationCompositionDefinition acDefinition) {
483 for (var element : automationComposition.getElements().entrySet()) {
484 var elementId = element.getKey();
485 var dbAcElement = acFromDb.getElements().get(elementId);
486 if (dbAcElement == null) {
487 LOGGER.info("New Ac element {} added in Migration", elementId);
488 element.getValue().setMigrationState(MigrationState.NEW);
489 acFromDb.getElements().put(elementId, element.getValue());
491 AcmUtils.recursiveMerge(dbAcElement.getProperties(), element.getValue().getProperties());
492 var newDefinition = element.getValue().getDefinition().asConceptKey();
493 var dbElementDefinition = dbAcElement.getDefinition().asConceptKey();
494 AutomationCompositionProvider.checkCompatibility(
495 newDefinition, dbElementDefinition, automationComposition.getInstanceId());
496 dbAcElement.setDefinition(element.getValue().getDefinition());
499 // Update migrationState for the removed elements
500 var elementsRemoved = getElementRemoved(acFromDb, automationComposition);
501 elementsRemoved.forEach(element -> acFromDb.getElements().get(element.getId())
502 .setMigrationState(MigrationState.REMOVED));
504 var validationResult = validateAutomationComposition(acFromDb, acDefinitionTarget, elementsRemoved.size());
505 if (!validationResult.isValid()) {
506 throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
508 associateParticipantId(acFromDb, acDefinitionTarget, acDefinition);
510 acFromDb.setCompositionTargetId(automationComposition.getCompositionTargetId());
513 private void associateParticipantId(AutomationComposition acFromDb,
514 AutomationCompositionDefinition acDefinitionTarget,
515 AutomationCompositionDefinition oldAcDefinition) {
516 for (var element : acFromDb.getElements().values()) {
517 var name = element.getDefinition().getName();
518 var migrationState = element.getMigrationState();
519 if (MigrationState.DEFAULT.equals(migrationState) || MigrationState.NEW.equals(migrationState)) {
520 var participantId = acDefinitionTarget.getElementStateMap().get(name).getParticipantId();
521 element.setParticipantId(participantId);
522 } else if (MigrationState.REMOVED.equals(migrationState) && oldAcDefinition != null) {
523 var participantId = oldAcDefinition.getElementStateMap().get(name).getParticipantId();
524 element.setParticipantId(participantId);
529 private AutomationCompositionDefinition getAcDefinition(UUID compositionId,
530 AutomationComposition automationComposition) {
531 AutomationCompositionProvider.validateInstanceEndpoint(compositionId, automationComposition);
532 var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId());
533 participantProvider.checkRegisteredParticipant(acDefinition);
538 * Retrieves a list of AutomationComposition instances filtered by the specified state change results
539 * and deployment states. The result can be paginated and sorted based on the provided parameters.
541 * @param instanceIds a list of instance UUIDs
542 * @param stateChangeResults a list of StateChangeResult values to filter the AutomationComposition instances
543 * @param deployStates a list of DeployState values to filter the AutomationComposition instances
544 * @param pageable the pagination information including page size and page number
545 * @return a list of AutomationComposition instances that match the specified filters
547 public AutomationCompositions getAcInstancesByFilter(
548 final String instanceIds, final String stateChangeResults, final String deployStates,
549 final Pageable pageable) {
551 LOGGER.info("Get automation compositions request received with filters");
552 List<String> acIds = new ArrayList<>();
553 if (instanceIds != null) {
554 Arrays.stream(instanceIds.split(",")).forEach(acId -> acIds.add(acId.trim()));
557 List<StateChangeResult> stateChangeResultList = new ArrayList<>();
558 if (stateChangeResults != null) {
559 Arrays.stream(stateChangeResults.split(","))
560 .forEach(stateChangeResult -> stateChangeResultList.add(StateChangeResult.valueOf(stateChangeResult)));
563 List<DeployState> deployStateList = new ArrayList<>();
564 if (deployStates != null) {
565 Arrays.stream(deployStates.split(","))
566 .forEach(deployState -> deployStateList.add(DeployState.valueOf(deployState)));
569 var instances = automationCompositionProvider.getAcInstancesByFilter(acIds, stateChangeResultList,
570 deployStateList, pageable);
571 return new AutomationCompositions(instances);