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.ParticipantUtils;
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.AcmUtils;
55 import org.onap.policy.common.parameters.BeanValidationResult;
56 import org.onap.policy.models.base.PfModelRuntimeException;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59 import org.springframework.data.domain.Pageable;
60 import org.springframework.stereotype.Service;
61 import org.springframework.transaction.annotation.Transactional;
64 * This class is dedicated to the Instantiation of Commissioned automation composition.
68 @RequiredArgsConstructor
69 public class AutomationCompositionInstantiationProvider {
70 private static final String DO_NOT_MATCH = " do not match with ";
71 private static final String ELEMENT_ID_NOT_PRESENT = "Element id not present ";
72 private static final String NOT_VALID_ORDER =
73 "Not valid order %s; DeployState: %s; LockState: %s; SubState: %s; StateChangeResult: %s";
75 private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionInstantiationProvider.class);
77 private final AutomationCompositionProvider automationCompositionProvider;
78 private final AcDefinitionProvider acDefinitionProvider;
79 private final AcInstanceStateResolver acInstanceStateResolver;
80 private final SupervisionAcHandler supervisionAcHandler;
81 private final ParticipantProvider participantProvider;
82 private final AcRuntimeParameterGroup acRuntimeParameterGroup;
83 private final EncryptionUtils encryptionUtils;
86 * Create automation composition.
88 * @param compositionId The UUID of the automation composition definition
89 * @param automationComposition the automation composition
90 * @return the result of the instantiation operation
92 public InstantiationResponse createAutomationComposition(UUID compositionId,
93 AutomationComposition automationComposition) {
94 LOGGER.info("Create instance request received for compositionId {}", compositionId);
95 AutomationCompositionProvider.validateInstanceEndpoint(compositionId, automationComposition);
96 automationCompositionProvider.validateNameVersion(automationComposition.getKey().asIdentifier());
98 var acDefinition = acDefinitionProvider.getAcDefinition(compositionId);
99 AcDefinitionProvider.checkPrimedComposition(acDefinition);
100 var validationResult = validateAutomationComposition(automationComposition, acDefinition);
101 if (!validationResult.isValid()) {
102 throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
104 encryptInstanceProperties(automationComposition, compositionId);
105 automationComposition = automationCompositionProvider.createAutomationComposition(automationComposition);
107 return createInstantiationResponse(automationComposition);
110 private InstantiationResponse createInstantiationResponse(AutomationComposition automationComposition) {
111 var response = new InstantiationResponse();
112 response.setInstanceId(automationComposition.getInstanceId());
113 response.setAffectedAutomationComposition(automationComposition.getKey().asIdentifier());
118 * Update automation composition.
120 * @param compositionId The UUID of the automation composition definition
121 * @param automationComposition the automation composition
122 * @return the result of the update
124 public InstantiationResponse updateAutomationComposition(UUID compositionId,
125 AutomationComposition automationComposition) {
126 var instanceId = automationComposition.getInstanceId();
127 var acToUpdate = automationCompositionProvider.getAutomationComposition(instanceId);
128 AutomationCompositionProvider.validateInstanceEndpoint(compositionId, acToUpdate);
129 var acDefinition = acDefinitionProvider.getAcDefinition(compositionId);
130 AcDefinitionProvider.checkPrimedComposition(acDefinition);
131 if (DeployState.UNDEPLOYED.equals(acToUpdate.getDeployState())) {
132 LOGGER.info("Updating undeployed instance with id {}", instanceId);
133 acToUpdate.setElements(automationComposition.getElements());
134 acToUpdate.setName(automationComposition.getName());
135 acToUpdate.setVersion(automationComposition.getVersion());
136 acToUpdate.setDescription(automationComposition.getDescription());
137 acToUpdate.setDerivedFrom(automationComposition.getDerivedFrom());
138 var validationResult = validateAutomationComposition(acToUpdate, acDefinition);
139 if (!validationResult.isValid()) {
140 throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
142 encryptInstanceProperties(acToUpdate, compositionId);
143 automationComposition = automationCompositionProvider.updateAutomationComposition(acToUpdate);
144 return createInstantiationResponse(automationComposition);
148 var deployOrder = DeployOrder.UPDATE;
149 var subOrder = SubOrder.NONE;
151 if (automationComposition.getCompositionTargetId() != null) {
153 if (Boolean.TRUE.equals(automationComposition.getPrecheck())) {
154 subOrder = SubOrder.MIGRATE_PRECHECK;
155 deployOrder = DeployOrder.NONE;
157 deployOrder = DeployOrder.MIGRATE;
160 var result = acInstanceStateResolver.resolve(deployOrder, LockOrder.NONE, subOrder,
161 acToUpdate.getDeployState(), acToUpdate.getLockState(), acToUpdate.getSubState(),
162 acToUpdate.getStateChangeResult());
163 return switch (result) {
164 case "UPDATE" -> updateDeployedAutomationComposition(automationComposition, acToUpdate, acDefinition);
166 case "MIGRATE" -> migrateAutomationComposition(automationComposition, acToUpdate, acDefinition);
168 case "MIGRATE_PRECHECK" -> migratePrecheckAc(automationComposition, acToUpdate, acDefinition);
170 default -> throw new PfModelRuntimeException(Status.BAD_REQUEST,
171 "Not allowed to " + deployOrder + " in the state " + acToUpdate.getDeployState());
176 * Update deployed AC Element properties.
178 * @param automationComposition the automation composition
179 * @param acToBeUpdated the composition to be updated
180 * @return the result of the update
182 private InstantiationResponse updateDeployedAutomationComposition(
183 AutomationComposition automationComposition, AutomationComposition acToBeUpdated,
184 AutomationCompositionDefinition acDefinition) {
185 // save copy in case of a rollback
186 automationCompositionProvider.copyAcElementsBeforeUpdate(acToBeUpdated);
187 LOGGER.info("Updating deployed instance with id {}", automationComposition.getInstanceId());
189 // Iterate and update the element property values
190 for (var element : automationComposition.getElements().entrySet()) {
191 var elementId = element.getKey();
192 var dbAcElement = acToBeUpdated.getElements().get(elementId);
193 if (dbAcElement == null) {
194 throw new PfModelRuntimeException(Status.BAD_REQUEST, ELEMENT_ID_NOT_PRESENT + elementId);
196 AcmUtils.recursiveMerge(dbAcElement.getProperties(), element.getValue().getProperties());
199 var validationResult = validateAutomationComposition(acToBeUpdated, acDefinition);
200 if (!validationResult.isValid()) {
201 throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
203 updateAcForProperties(acToBeUpdated);
205 var acToPublish = new AutomationComposition(acToBeUpdated);
206 encryptInstanceProperties(acToBeUpdated, acToBeUpdated.getCompositionId());
208 automationComposition = automationCompositionProvider.updateAutomationComposition(acToBeUpdated);
209 // Publish property update event to the participants
210 supervisionAcHandler.update(acToPublish, acDefinition.getRevisionId());
211 return createInstantiationResponse(automationComposition);
214 private InstantiationResponse migrateAutomationComposition(
215 AutomationComposition automationComposition, AutomationComposition acToBeUpdated,
216 AutomationCompositionDefinition acDefinition) {
217 LOGGER.info("Migrating instance with id {}", automationComposition.getInstanceId());
218 if (!DeployState.DEPLOYED.equals(acToBeUpdated.getDeployState())) {
219 throw new PfModelRuntimeException(Status.BAD_REQUEST,
220 "Not allowed to migrate in the state " + acToBeUpdated.getDeployState());
222 // make copy for rollback
223 automationCompositionProvider.copyAcElementsBeforeUpdate(acToBeUpdated);
225 var acDefinitionTarget = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionTargetId());
226 AcDefinitionProvider.checkPrimedComposition(acDefinitionTarget);
227 // Iterate and update the element property values
228 var elementsRemoved = updateElementsProperties(automationComposition, acToBeUpdated, acDefinitionTarget);
230 updateAcForMigration(acToBeUpdated, acDefinitionTarget, DeployState.MIGRATING);
232 var acToPublish = new AutomationComposition(acToBeUpdated);
233 encryptInstanceProperties(acToBeUpdated, acToBeUpdated.getCompositionTargetId());
235 var ac = automationCompositionProvider.updateAutomationComposition(acToBeUpdated);
236 for (var element : elementsRemoved) {
237 automationCompositionProvider.deleteAutomationCompositionElement(element.getId());
240 // Publish migrate event to the participants
241 supervisionAcHandler.migrate(acToPublish, acDefinition.getRevisionId(), acDefinitionTarget.getRevisionId(),
243 return createInstantiationResponse(ac);
246 private void updateAcForMigration(AutomationComposition acToBeUpdated,
247 AutomationCompositionDefinition acDefinition, DeployState deployState) {
248 AcmUtils.setCascadedState(acToBeUpdated, deployState, LockState.LOCKED);
249 acToBeUpdated.setStateChangeResult(StateChangeResult.NO_ERROR);
250 var stage = ParticipantUtils.getFirstStage(acToBeUpdated, acDefinition.getServiceTemplate());
251 acToBeUpdated.setPhase(stage);
254 private void updateAcForProperties(AutomationComposition acToBeUpdated) {
255 AcmUtils.setCascadedState(acToBeUpdated, DeployState.UPDATING, acToBeUpdated.getLockState());
256 acToBeUpdated.setStateChangeResult(StateChangeResult.NO_ERROR);
259 private List<AutomationCompositionElement> getElementRemoved(AutomationComposition acFromDb,
260 AutomationComposition acFromMigration) {
261 return acFromDb.getElements().values().stream()
262 .filter(element -> acFromMigration.getElements().get(element.getId()) == null).toList();
266 private InstantiationResponse migratePrecheckAc(
267 AutomationComposition automationComposition, AutomationComposition acToBeUpdated,
268 AutomationCompositionDefinition acDefinition) {
270 acToBeUpdated.setPrecheck(true);
271 LOGGER.info("Running migrate precheck for id: {}", automationComposition.getInstanceId());
272 var copyAc = new AutomationComposition(acToBeUpdated);
273 var acDefinitionTarget = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionTargetId());
274 AcDefinitionProvider.checkPrimedComposition(acDefinitionTarget);
275 // Iterate and update the element property values
276 var removedElements = updateElementsProperties(automationComposition, copyAc, acDefinitionTarget);
278 // Publish migrate event to the participants
279 supervisionAcHandler.migratePrecheck(copyAc, acDefinition.getRevisionId(), acDefinitionTarget.getRevisionId(),
282 AcmUtils.setCascadedState(acToBeUpdated, DeployState.DEPLOYED, LockState.LOCKED,
283 SubState.MIGRATION_PRECHECKING);
284 acToBeUpdated.setStateChangeResult(StateChangeResult.NO_ERROR);
286 return createInstantiationResponse(automationCompositionProvider.updateAutomationComposition(acToBeUpdated));
290 * Validate AutomationComposition.
292 * @param automationComposition AutomationComposition to validate
293 * @param acDefinition the Composition Definition
294 * @return the result of validation
296 private BeanValidationResult validateAutomationComposition(AutomationComposition automationComposition,
297 AutomationCompositionDefinition acDefinition) {
298 var result = new BeanValidationResult("AutomationComposition", automationComposition);
299 participantProvider.checkRegisteredParticipant(acDefinition);
300 result.addResult(AcmUtils.validateAutomationComposition(automationComposition,
301 acDefinition.getServiceTemplate(),
302 acRuntimeParameterGroup.getAcmParameters().getToscaCompositionName()));
304 result.addResult(automationCompositionProvider.validateElementIds(automationComposition));
306 if (result.isValid()) {
307 for (var element : automationComposition.getElements().values()) {
308 var name = element.getDefinition().getName();
309 var participantId = acDefinition.getElementStateMap().get(name).getParticipantId();
310 element.setParticipantId(participantId);
318 private void encryptInstanceProperties(AutomationComposition automationComposition, UUID compositionId) {
319 if (encryptionUtils.encryptionEnabled()) {
320 var acDefinitionOpt = acDefinitionProvider.findAcDefinition(compositionId);
321 acDefinitionOpt.ifPresent(acDefinition
322 -> encryptionUtils.findAndEncryptSensitiveData(acDefinition, automationComposition));
327 * Get Automation Composition.
329 * @param compositionId The UUID of the automation composition definition
330 * @param instanceId The UUID of the automation composition instance
331 * @return the Automation Composition
333 @Transactional(readOnly = true)
334 public AutomationComposition getAutomationComposition(@NonNull UUID compositionId, UUID instanceId) {
335 var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
336 if (!compositionId.equals(automationComposition.getCompositionId())
337 && !compositionId.equals(automationComposition.getCompositionTargetId())) {
338 throw new PfModelRuntimeException(Status.BAD_REQUEST,
339 automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
341 return automationComposition;
345 * Delete the automation composition with the given name and version.
347 * @param compositionId The UUID of the automation composition definition
348 * @param instanceId The UUID of the automation composition instance
349 * @return the result of the deletion
351 public InstantiationResponse deleteAutomationComposition(UUID compositionId, UUID instanceId) {
352 var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
353 var acDefinition = getAcDefinition(compositionId, automationComposition);
354 LOGGER.info("Delete automation composition request received for name: {} and version: {}",
355 automationComposition.getName(), automationComposition.getVersion());
356 var result = acInstanceStateResolver.resolve(DeployOrder.DELETE,
358 automationComposition.getDeployState(), automationComposition.getLockState(),
359 automationComposition.getSubState(), automationComposition.getStateChangeResult());
360 if (!DeployOrder.DELETE.name().equals(result)) {
361 var msg = String.format(NOT_VALID_ORDER, DeployOrder.DELETE,
362 automationComposition.getDeployState(), automationComposition.getLockState(),
363 automationComposition.getSubState(), automationComposition.getStateChangeResult());
364 throw new PfModelRuntimeException(Status.BAD_REQUEST, msg);
366 supervisionAcHandler.delete(automationComposition, acDefinition);
367 return createInstantiationResponse(automationComposition);
371 * Get the requested automation compositions.
373 * @param name the name of the automation composition to get, null for all automation compositions
374 * @param version the version of the automation composition to get, null for all automation compositions
375 * @param pageable the Pageable
376 * @return the automation compositions
378 @Transactional(readOnly = true)
379 public AutomationCompositions getAutomationCompositions(@NonNull final UUID compositionId,
380 final String name, final String version,
381 @NonNull final Pageable pageable) {
382 var automationCompositions = new AutomationCompositions();
383 automationCompositions.setAutomationCompositionList(
384 automationCompositionProvider.getAutomationCompositions(compositionId, name, version, pageable));
386 return automationCompositions;
390 * Handle Composition Instance State.
392 * @param compositionId the compositionId
393 * @param instanceId the instanceId
394 * @param acInstanceStateUpdate the AcInstanceStateUpdate
396 public void compositionInstanceState(UUID compositionId, UUID instanceId,
397 @Valid AcInstanceStateUpdate acInstanceStateUpdate) {
398 var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
399 var acDefinition = getAcDefinition(compositionId, automationComposition);
400 var result = acInstanceStateResolver.resolve(acInstanceStateUpdate.getDeployOrder(),
401 acInstanceStateUpdate.getLockOrder(), acInstanceStateUpdate.getSubOrder(),
402 automationComposition.getDeployState(), automationComposition.getLockState(),
403 automationComposition.getSubState(), automationComposition.getStateChangeResult());
406 supervisionAcHandler.deploy(automationComposition, acDefinition);
410 supervisionAcHandler.undeploy(automationComposition, acDefinition);
414 supervisionAcHandler.lock(automationComposition, acDefinition);
418 supervisionAcHandler.unlock(automationComposition, acDefinition);
422 supervisionAcHandler.prepare(automationComposition, acDefinition);
426 supervisionAcHandler.review(automationComposition, acDefinition);
430 var msg = String.format(NOT_VALID_ORDER, acInstanceStateUpdate,
431 automationComposition.getDeployState(), automationComposition.getLockState(),
432 automationComposition.getSubState(), automationComposition.getStateChangeResult());
433 throw new PfModelRuntimeException(Status.BAD_REQUEST, msg);
438 * Rollback AC Instance.
440 * @param compositionId The UUID of the automation composition definition
441 * @param instanceId The UUID of the automation composition instance
443 public void rollback(UUID compositionId, UUID instanceId) {
444 LOGGER.info("Rollback automation composition request received for CompositionID: {} and InstanceID: {}",
445 compositionId, instanceId);
446 var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
447 AutomationCompositionProvider.validateInstanceEndpoint(compositionId, automationComposition);
449 if (!DeployOrder.MIGRATION_REVERT.name().equals(acInstanceStateResolver.resolve(
450 DeployOrder.MIGRATION_REVERT, LockOrder.NONE,
451 SubOrder.NONE, automationComposition.getDeployState(), automationComposition.getLockState(),
452 automationComposition.getSubState(), automationComposition.getStateChangeResult()))) {
453 throw new PfModelRuntimeException(Status.BAD_REQUEST, "Invalid state for rollback");
456 var automationCompositionToRollback =
457 automationCompositionProvider.getAutomationCompositionRollback(instanceId);
458 var acToBeUpdated = new AutomationComposition(automationComposition);
459 acToBeUpdated.setCompositionTargetId(automationCompositionToRollback.getCompositionId());
460 acToBeUpdated.setElements(automationCompositionToRollback.getElements().values().stream()
461 .collect(Collectors.toMap(AutomationCompositionElement::getId, AutomationCompositionElement::new)));
463 var acDefinitionTarget = acDefinitionProvider.getAcDefinition(acToBeUpdated.getCompositionTargetId());
464 var validationResult = validateAutomationComposition(acToBeUpdated, acDefinitionTarget);
465 if (!validationResult.isValid()) {
466 throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
469 updateAcForMigration(acToBeUpdated, acDefinitionTarget, DeployState.MIGRATION_REVERTING);
470 var elementsRemoved = getElementRemoved(automationComposition, acToBeUpdated);
471 automationCompositionProvider.updateAutomationComposition(acToBeUpdated);
472 for (var element : elementsRemoved) {
473 automationCompositionProvider.deleteAutomationCompositionElement(element.getId());
475 var acDefinition = acDefinitionProvider.getAcDefinition(acToBeUpdated.getCompositionId());
476 supervisionAcHandler.migrate(acToBeUpdated, acDefinition.getRevisionId(), acDefinitionTarget.getRevisionId(),
480 private List<AutomationCompositionElement> updateElementsProperties(AutomationComposition automationComposition,
481 AutomationComposition acToBeUpdated, AutomationCompositionDefinition acDefinitionTarget) {
482 for (var element : automationComposition.getElements().entrySet()) {
483 var elementId = element.getKey();
484 var dbAcElement = acToBeUpdated.getElements().get(elementId);
485 // Add additional elements if present for migration
486 if (dbAcElement == null) {
487 LOGGER.info("New Ac element {} added in Migration", elementId);
488 acToBeUpdated.getElements().put(elementId, element.getValue());
490 AcmUtils.recursiveMerge(dbAcElement.getProperties(), element.getValue().getProperties());
491 var newDefinition = element.getValue().getDefinition().asConceptKey();
492 var dbElementDefinition = dbAcElement.getDefinition().asConceptKey();
493 AutomationCompositionProvider.checkCompatibility(
494 newDefinition, dbElementDefinition, automationComposition.getInstanceId());
495 dbAcElement.setDefinition(element.getValue().getDefinition());
498 // Remove elements which are not present in the new Ac instance
499 var elementsRemoved = getElementRemoved(acToBeUpdated, automationComposition);
500 elementsRemoved.forEach(element -> acToBeUpdated.getElements().remove(element.getId()));
502 var validationResult = validateAutomationComposition(acToBeUpdated, acDefinitionTarget);
503 if (!validationResult.isValid()) {
504 throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
506 acToBeUpdated.setCompositionTargetId(automationComposition.getCompositionTargetId());
507 return elementsRemoved;
510 private AutomationCompositionDefinition getAcDefinition(UUID compositionId,
511 AutomationComposition automationComposition) {
512 AutomationCompositionProvider.validateInstanceEndpoint(compositionId, automationComposition);
513 var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId());
514 participantProvider.checkRegisteredParticipant(acDefinition);
519 * Retrieves a list of AutomationComposition instances filtered by the specified state change results
520 * and deployment states. The result can be paginated and sorted based on the provided parameters.
522 * @param instanceIds a list of instance UUIDs
523 * @param stateChangeResults a list of StateChangeResult values to filter the AutomationComposition instances
524 * @param deployStates a list of DeployState values to filter the AutomationComposition instances
525 * @param pageable the pagination information including page size and page number
526 * @return a list of AutomationComposition instances that match the specified filters
528 public AutomationCompositions getAcInstancesByFilter(
529 final String instanceIds, final String stateChangeResults, final String deployStates,
530 final Pageable pageable) {
532 LOGGER.info("Get automation compositions request received with filters");
533 List<String> acIds = new ArrayList<>();
534 if (instanceIds != null) {
535 Arrays.stream(instanceIds.split(",")).forEach(acId -> acIds.add(acId.trim()));
538 List<StateChangeResult> stateChangeResultList = new ArrayList<>();
539 if (stateChangeResults != null) {
540 Arrays.stream(stateChangeResults.split(","))
541 .forEach(stateChangeResult -> stateChangeResultList.add(StateChangeResult.valueOf(stateChangeResult)));
544 List<DeployState> deployStateList = new ArrayList<>();
545 if (deployStates != null) {
546 Arrays.stream(deployStates.split(","))
547 .forEach(deployState -> deployStateList.add(DeployState.valueOf(deployState)));
550 var instances = automationCompositionProvider.getAcInstancesByFilter(acIds, stateChangeResultList,
551 deployStateList, pageable);
552 return new AutomationCompositions(instances);