From: adheli.tavares Date: Thu, 5 Jun 2025 10:49:47 +0000 (+0100) Subject: Rollback of automation composition migration/update X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F10%2F141110%2F3;p=policy%2Fclamp.git Rollback of automation composition migration/update - copy of ac + elements to rollback table Issue-ID: POLICY-5362 Change-Id: I1df199d3a4daa7110b5d0b69044f1ad91797516a Signed-off-by: adheli.tavares --- diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionDefinition.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionDefinition.java index 57b6837af..0fee98b15 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionDefinition.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionDefinition.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022-2024 Nordix Foundation. + * Copyright (C) 2022-2025 OpenInfra Foundation Europe. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,7 +54,7 @@ public class AutomationCompositionDefinition { private Map elementStateMap = new HashMap<>(); /** - * Copy contructor, does a deep copy. + * Copy constructor, does a deep copy. * * @param otherAcmDefinition the other element to copy from */ diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionRollback.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionRollback.java index 730a08dcb..3d62f91e3 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionRollback.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionRollback.java @@ -27,7 +27,6 @@ import java.util.function.UnaryOperator; import lombok.Data; import lombok.NoArgsConstructor; import lombok.NonNull; -import lombok.ToString; import org.onap.policy.models.base.PfUtils; @NoArgsConstructor @@ -53,4 +52,19 @@ public class AutomationCompositionRollback { this.compositionId = otherAcmRollback.compositionId; this.elements = PfUtils.mapMap(otherAcmRollback.elements, UnaryOperator.identity()); } + + /** + * Create a copy from an automation composition. + * + * @param automationComposition the composition being migrated that needs a copy + */ + public AutomationCompositionRollback(final AutomationComposition automationComposition) { + this.instanceId = automationComposition.getInstanceId(); + this.compositionId = automationComposition.getCompositionId(); + var originalElements = automationComposition.getElements(); + + this.elements = new LinkedHashMap<>(); + originalElements.forEach((uuid, element) -> + this.elements.put(uuid.toString(), element)); + } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionDefinition.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionDefinition.java index 02ec19a6f..cbf21e6fe 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionDefinition.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionDefinition.java @@ -53,7 +53,7 @@ import org.onap.policy.models.base.PfKey; import org.onap.policy.models.base.Validated; /** - * Class to represent a automation composition definition in the database. + * Class to represent an automation composition definition in the database. */ @Entity @Table(name = "AutomationCompositionDefinition") diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java index 287ae5171..5d2c4f26c 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java @@ -33,12 +33,15 @@ import lombok.AllArgsConstructor; import lombok.NonNull; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionRollback; import org.onap.policy.clamp.models.acm.concepts.DeployState; import org.onap.policy.clamp.models.acm.concepts.LockState; import org.onap.policy.clamp.models.acm.concepts.SubState; import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationComposition; +import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionRollback; import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionElementRepository; import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionRepository; +import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionRollbackRepository; import org.onap.policy.clamp.models.acm.utils.AcmUtils; import org.onap.policy.common.parameters.BeanValidationResult; import org.onap.policy.common.parameters.ValidationStatus; @@ -60,6 +63,7 @@ public class AutomationCompositionProvider { private final AutomationCompositionRepository automationCompositionRepository; private final AutomationCompositionElementRepository acElementRepository; + private final AutomationCompositionRollbackRepository acRollbackRepository; /** * Get automation composition. @@ -96,23 +100,23 @@ public class AutomationCompositionProvider { */ @Transactional(readOnly = true) public Optional findAutomationComposition( - final ToscaConceptIdentifier automationCompositionId) { + final ToscaConceptIdentifier automationCompositionId) { return automationCompositionRepository - .findOne(createExample(null, automationCompositionId.getName(), automationCompositionId.getVersion())) - .map(JpaAutomationComposition::toAuthorative); + .findOne(createExample(null, automationCompositionId.getName(), automationCompositionId.getVersion())) + .map(JpaAutomationComposition::toAuthorative); } /** * Create automation composition. * * @param automationComposition the automation composition to create - * @return the create automation composition + * @return the created automation composition */ public AutomationComposition createAutomationComposition(final AutomationComposition automationComposition) { automationComposition.setInstanceId(UUID.randomUUID()); AcmUtils.setCascadedState(automationComposition, DeployState.UNDEPLOYED, LockState.NONE); var result = automationCompositionRepository.save(ProviderUtils.getJpaAndValidate(automationComposition, - JpaAutomationComposition::new, "automation composition")); + JpaAutomationComposition::new, "automation composition")); // Return the saved automation composition return result.toAuthorative(); @@ -125,9 +129,9 @@ public class AutomationCompositionProvider { * @return the updated automation composition */ public AutomationComposition updateAutomationComposition( - @NonNull final AutomationComposition automationComposition) { + @NonNull final AutomationComposition automationComposition) { var result = automationCompositionRepository.save(ProviderUtils.getJpaAndValidate(automationComposition, - JpaAutomationComposition::new, "automation composition")); + JpaAutomationComposition::new, "automation composition")); automationCompositionRepository.flush(); // Return the saved automation composition return result.toAuthorative(); @@ -142,11 +146,11 @@ public class AutomationCompositionProvider { @Transactional(readOnly = true) public List getAcInstancesByCompositionId(UUID compositionId) { return ProviderUtils - .asEntityList(automationCompositionRepository.findByCompositionId(compositionId.toString())); + .asEntityList(automationCompositionRepository.findByCompositionId(compositionId.toString())); } /** - * Get all automation compositions in transition.. + * Get all automation compositions in transition. * * @return all automation compositions found */ @@ -157,28 +161,29 @@ public class AutomationCompositionProvider { jpaList.addAll(automationCompositionRepository.findByLockStateIn( List.of(LockState.LOCKING, LockState.UNLOCKING))); jpaList.addAll(automationCompositionRepository.findBySubStateIn( - List.of(SubState.PREPARING, SubState.MIGRATION_PRECHECKING, SubState.REVIEWING))); + List.of(SubState.PREPARING, SubState.MIGRATION_PRECHECKING, SubState.REVIEWING))); return jpaList.stream().map(JpaAutomationComposition::getInstanceId) - .map(UUID::fromString).collect(Collectors.toSet()); + .map(UUID::fromString).collect(Collectors.toSet()); } /** * Get automation compositions. * - * @param name the name of the automation composition to get, null to get all automation compositions - * @param version the version of the automation composition to get, null to get all automation compositions + * @param name the name of the automation composition to get, null to get all automation compositions + * @param version the version of the automation composition to get, null to get all automation compositions * @param pageable the Pageable * @return the automation compositions found */ @Transactional(readOnly = true) public List getAutomationCompositions(@NonNull final UUID compositionId, final String name, - final String version, @NonNull final Pageable pageable) { + final String version, + @NonNull final Pageable pageable) { return ProviderUtils.asEntityList(automationCompositionRepository - .findAll(createExample(compositionId, name, version), pageable).toList()); + .findAll(createExample(compositionId, name, version), pageable).toList()); } private Example createExample(final UUID compositionId, final String name, - final String version) { + final String version) { var example = new JpaAutomationComposition(); example.setCompositionId(compositionId != null ? compositionId.toString() : null); example.setName(name); @@ -201,7 +206,7 @@ public class AutomationCompositionProvider { var jpaDeleteAutomationComposition = automationCompositionRepository.findById(instanceId.toString()); if (jpaDeleteAutomationComposition.isEmpty()) { var errorMessage = "delete of automation composition \"" + instanceId - + "\" failed, automation composition does not exist"; + + "\" failed, automation composition does not exist"; throw new PfModelRuntimeException(Response.Status.NOT_FOUND, errorMessage); } @@ -249,4 +254,16 @@ public class AutomationCompositionProvider { } return result; } + + /** + * Save a copy of an automation composition to the copy table in case of a rollback. + * + * @param automationComposition the composition to be copied + */ + public void copyAcElementsBeforeUpdate(AutomationComposition automationComposition) { + var copy = new AutomationCompositionRollback(automationComposition); + var jpaCopy = new JpaAutomationCompositionRollback(copy); + acRollbackRepository.save(jpaCopy); + acRollbackRepository.flush(); + } } diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionRollbackTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionRollbackTest.java index a6273a9e4..94d899e4d 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionRollbackTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionRollbackTest.java @@ -34,7 +34,7 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionRollback; import org.onap.policy.models.base.PfUtils; -public class JpaAutomationCompositionRollbackTest { +class JpaAutomationCompositionRollbackTest { private static final String NULL_INSTANCE_ID_ERROR = "instanceId is marked .*ull but is null"; private static final String NULL_ERROR = " is marked .*ull but is null"; diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProviderTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProviderTest.java index c6ce2e08a..71134768c 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProviderTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProviderTest.java @@ -41,12 +41,13 @@ import org.onap.policy.clamp.models.acm.concepts.DeployState; import org.onap.policy.clamp.models.acm.concepts.LockState; import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationComposition; import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionElement; +import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionRollback; import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionElementRepository; import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionRepository; +import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionRollbackRepository; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.common.utils.resources.ResourceUtils; -import org.springframework.data.domain.Example; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -58,28 +59,37 @@ class AutomationCompositionProviderTest { private static final Coder CODER = new StandardCoder(); private static final String AUTOMATION_COMPOSITION_JSON = - "src/test/resources/providers/TestAutomationCompositions.json"; + "src/test/resources/providers/TestAutomationCompositions.json"; private AutomationCompositions inputAutomationCompositions; private List inputAutomationCompositionsJpa; private final String originalJson = ResourceUtils.getResourceAsString(AUTOMATION_COMPOSITION_JSON); + private AutomationCompositionProvider automationCompositionProvider; + private AutomationCompositionRepository automationCompositionRepository; + private AutomationCompositionElementRepository acElementRepository; + private AutomationCompositionRollbackRepository acRollbackRepository; + @BeforeEach void beforeSetupDao() throws Exception { inputAutomationCompositions = CODER.decode(originalJson, AutomationCompositions.class); inputAutomationCompositionsJpa = - ProviderUtils.getJpaAndValidateList(inputAutomationCompositions.getAutomationCompositionList(), - JpaAutomationComposition::new, "automation compositions"); + ProviderUtils.getJpaAndValidateList(inputAutomationCompositions.getAutomationCompositionList(), + JpaAutomationComposition::new, "automation compositions"); + + // set mocks + automationCompositionRepository = mock(AutomationCompositionRepository.class); + acElementRepository = mock(AutomationCompositionElementRepository.class); + acRollbackRepository = mock(AutomationCompositionRollbackRepository.class); + automationCompositionProvider = + new AutomationCompositionProvider(automationCompositionRepository, acElementRepository, + acRollbackRepository); } @Test void testAutomationCompositionCreate() { - var automationCompositionRepository = mock(AutomationCompositionRepository.class); - var automationCompositionProvider = new AutomationCompositionProvider(automationCompositionRepository, - mock(AutomationCompositionElementRepository.class)); - when(automationCompositionRepository.save(any(JpaAutomationComposition.class))) - .thenReturn(inputAutomationCompositionsJpa.get(0)); + .thenReturn(inputAutomationCompositionsJpa.get(0)); var inputAc = inputAutomationCompositions.getAutomationCompositionList().get(0); var createdAutomationComposition = automationCompositionProvider.createAutomationComposition(inputAc); @@ -90,56 +100,45 @@ class AutomationCompositionProviderTest { @Test void testAutomationCompositionUpdate() { - var automationCompositionRepository = mock(AutomationCompositionRepository.class); - var automationCompositionProvider = new AutomationCompositionProvider(automationCompositionRepository, - mock(AutomationCompositionElementRepository.class)); - assertThatThrownBy(() -> automationCompositionProvider.updateAutomationComposition(null)) - .hasMessageMatching(AC_IS_NULL); + .hasMessageMatching(AC_IS_NULL); when(automationCompositionRepository.save(inputAutomationCompositionsJpa.get(0))) - .thenReturn(inputAutomationCompositionsJpa.get(0)); + .thenReturn(inputAutomationCompositionsJpa.get(0)); var createdAutomationComposition = automationCompositionProvider - .updateAutomationComposition(inputAutomationCompositions.getAutomationCompositionList().get(0)); + .updateAutomationComposition(inputAutomationCompositions.getAutomationCompositionList().get(0)); assertEquals(inputAutomationCompositions.getAutomationCompositionList().get(0), createdAutomationComposition); } @Test void testGetAutomationCompositionsWithNull() { - var automationCompositionProvider = new AutomationCompositionProvider( - mock(AutomationCompositionRepository.class), mock(AutomationCompositionElementRepository.class)); - assertThatThrownBy(() -> automationCompositionProvider - .getAutomationCompositions(UUID.randomUUID(), null, null, null)) - .hasMessage("pageable is marked non-null but is null"); + .getAutomationCompositions(UUID.randomUUID(), null, null, null)) + .hasMessage("pageable is marked non-null but is null"); assertThatThrownBy(() -> automationCompositionProvider - .getAutomationCompositions(null, null, null, Pageable.unpaged())) - .hasMessage("compositionId is marked non-null but is null"); + .getAutomationCompositions(null, null, null, Pageable.unpaged())) + .hasMessage("compositionId is marked non-null but is null"); } @Test void testGetAutomationCompositions() { - var automationCompositionRepository = mock(AutomationCompositionRepository.class); - var automationCompositionProvider = new AutomationCompositionProvider(automationCompositionRepository, - mock(AutomationCompositionElementRepository.class)); - var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0); when(automationCompositionRepository - .findAll(Mockito.>any(), any(Pageable.class))) - .thenReturn(new PageImpl<>(inputAutomationCompositionsJpa)); + .findAll(Mockito.any(), any(Pageable.class))) + .thenReturn(new PageImpl<>(inputAutomationCompositionsJpa)); var acList = automationCompositionProvider.getAutomationCompositions(UUID.randomUUID(), - automationComposition.getName(), automationComposition.getVersion(), Pageable.unpaged()); + automationComposition.getName(), automationComposition.getVersion(), Pageable.unpaged()); assertThat(acList).hasSize(2); acList = automationCompositionProvider.getAutomationCompositions(automationComposition.getCompositionId(), null, - null, Pageable.unpaged()); + null, Pageable.unpaged()); assertThat(acList).hasSize(2); when(automationCompositionRepository - .findAll(Mockito.>any(), Mockito.any(Pageable.class))) + .findAll(Mockito.any(), Mockito.any(Pageable.class))) .thenReturn(new PageImpl<>(inputAutomationCompositionsJpa)); acList = automationCompositionProvider.getAutomationCompositions(automationComposition.getCompositionId(), null, null, PageRequest.of(0, 10)); @@ -148,27 +147,19 @@ class AutomationCompositionProviderTest { @Test void testGetAutomationComposition() { - var automationCompositionRepository = mock(AutomationCompositionRepository.class); - var automationCompositionProvider = new AutomationCompositionProvider(automationCompositionRepository, - mock(AutomationCompositionElementRepository.class)); - var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0); assertThatThrownBy( - () -> automationCompositionProvider.getAutomationComposition(automationComposition.getInstanceId())) - .hasMessageMatching("AutomationComposition not found"); + () -> automationCompositionProvider.getAutomationComposition(automationComposition.getInstanceId())) + .hasMessageMatching("AutomationComposition not found"); when(automationCompositionRepository.findById(automationComposition.getInstanceId().toString())) - .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0))); + .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0))); var ac = automationCompositionProvider.getAutomationComposition(automationComposition.getInstanceId()); assertEquals(automationComposition, ac); } @Test void testFindAutomationComposition() { - var automationCompositionRepository = mock(AutomationCompositionRepository.class); - var automationCompositionProvider = new AutomationCompositionProvider(automationCompositionRepository, - mock(AutomationCompositionElementRepository.class)); - var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0); var acOpt = automationCompositionProvider.findAutomationComposition(automationComposition.getInstanceId()); assertThat(acOpt).isEmpty(); @@ -177,27 +168,23 @@ class AutomationCompositionProviderTest { assertThat(acOpt).isEmpty(); when(automationCompositionRepository.findById(automationComposition.getInstanceId().toString())) - .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0))); + .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0))); acOpt = automationCompositionProvider.findAutomationComposition(automationComposition.getInstanceId()); assertEquals(automationComposition, acOpt.get()); - when(automationCompositionRepository.findOne(Mockito.>any())) - .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0))); + when(automationCompositionRepository.findOne(Mockito.any())) + .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0))); acOpt = automationCompositionProvider.findAutomationComposition(automationComposition.getKey().asIdentifier()); assertEquals(automationComposition, acOpt.get()); } @Test void testGetAcInstancesByCompositionId() { - var automationCompositionRepository = mock(AutomationCompositionRepository.class); - var automationCompositionProvider = new AutomationCompositionProvider(automationCompositionRepository, - mock(AutomationCompositionElementRepository.class)); - var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0); when(automationCompositionRepository.findByCompositionId(automationComposition.getCompositionId().toString())) - .thenReturn(inputAutomationCompositionsJpa); + .thenReturn(inputAutomationCompositionsJpa); var acList = - automationCompositionProvider.getAcInstancesByCompositionId(automationComposition.getCompositionId()); + automationCompositionProvider.getAcInstancesByCompositionId(automationComposition.getCompositionId()); assertEquals(inputAutomationCompositions.getAutomationCompositionList(), acList); } @@ -210,9 +197,7 @@ class AutomationCompositionProviderTest { List res1 = new ArrayList<>(); res1.add(inputAutomationCompositionsJpa.get(0)); - var automationCompositionRepository = mock(AutomationCompositionRepository.class); - var automationCompositionProvider = new AutomationCompositionProvider(automationCompositionRepository, - mock(AutomationCompositionElementRepository.class)); + when(automationCompositionRepository.findByDeployStateIn(List.of(DeployState.DEPLOYING, DeployState.UNDEPLOYING, DeployState.DELETING, DeployState.UPDATING, DeployState.MIGRATING))) .thenReturn(res1); @@ -220,35 +205,28 @@ class AutomationCompositionProviderTest { .thenReturn(List.of(inputAutomationCompositionsJpa.get(1))); var acList = automationCompositionProvider.getAcInstancesInTransition(); assertThat(acList).hasSize(2) - .contains(inputAutomationCompositions.getAutomationCompositionList().get(0).getInstanceId()) - .contains(inputAutomationCompositions.getAutomationCompositionList().get(1).getInstanceId()); + .contains(inputAutomationCompositions.getAutomationCompositionList().get(0).getInstanceId()) + .contains(inputAutomationCompositions.getAutomationCompositionList().get(1).getInstanceId()); } @Test void testDeleteAutomationComposition() { - var automationCompositionRepository = mock(AutomationCompositionRepository.class); - var automationCompositionProvider = new AutomationCompositionProvider(automationCompositionRepository, - mock(AutomationCompositionElementRepository.class)); - assertThatThrownBy(() -> automationCompositionProvider.deleteAutomationComposition(UUID.randomUUID())) - .hasMessageMatching(".*.failed, automation composition does not exist"); + .hasMessageMatching(".*.failed, automation composition does not exist"); var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0); when(automationCompositionRepository.findById(automationComposition.getInstanceId().toString())) - .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0))); + .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0))); var deletedAc = - automationCompositionProvider.deleteAutomationComposition(automationComposition.getInstanceId()); + automationCompositionProvider.deleteAutomationComposition(automationComposition.getInstanceId()); assertEquals(automationComposition, deletedAc); } @Test void testDeleteElementById() { - var acElementRepository = mock(AutomationCompositionElementRepository.class); - var automationCompositionProvider = new AutomationCompositionProvider( - mock(AutomationCompositionRepository.class), acElementRepository); assertThatThrownBy(() -> automationCompositionProvider.deleteAutomationCompositionElement(null)) - .hasMessageMatching(ACELEMENT_ID_IS_NULL); + .hasMessageMatching(ACELEMENT_ID_IS_NULL); var elementId = UUID.randomUUID(); automationCompositionProvider.deleteAutomationCompositionElement(elementId); verify(acElementRepository).deleteById(elementId.toString()); @@ -256,10 +234,6 @@ class AutomationCompositionProviderTest { @Test void testValidateElementIds() { - var acElementRepository = mock(AutomationCompositionElementRepository.class); - var automationCompositionProvider = new AutomationCompositionProvider( - mock(AutomationCompositionRepository.class), acElementRepository); - var ac = inputAutomationCompositions.getAutomationCompositionList().get(0); var result = automationCompositionProvider.validateElementIds(ac); @@ -283,4 +257,12 @@ class AutomationCompositionProviderTest { result = automationCompositionProvider.validateElementIds(ac); assertThat(result.isValid()).isTrue(); } + + @Test + void testCopyAcElements() { + var ac = inputAutomationCompositions.getAutomationCompositionList().get(0); + automationCompositionProvider.copyAcElementsBeforeUpdate(ac); + + verify(acRollbackRepository).save(any(JpaAutomationCompositionRollback.class)); + } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java index edb3386e2..0d3375bae 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java @@ -50,7 +50,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** - * This class provides the create, read and delete actions on Commissioning of automation composition concepts in the + * This class provides the creation, read and delete actions on Commissioning of automation composition concepts in the * database to the callers. */ @Service @@ -202,7 +202,6 @@ public class CommissioningProvider { case DEPRIME: deprime(acmDefinition); - break; default: diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java index c015ceb71..59373e89b 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java @@ -73,7 +73,7 @@ public class AutomationCompositionInstantiationProvider { private static final String DO_NOT_MATCH = " do not match with "; private static final String ELEMENT_ID_NOT_PRESENT = "Element id not present "; private static final String NOT_VALID_ORDER = - "Not valid order %s; DeployState: %s; LockState: %s; SubState: %s; StateChangeResult: %s"; + "Not valid order %s; DeployState: %s; LockState: %s; SubState: %s; StateChangeResult: %s"; private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionInstantiationProvider.class); @@ -88,21 +88,18 @@ public class AutomationCompositionInstantiationProvider { /** * Create automation composition. * - * @param compositionId The UUID of the automation composition definition + * @param compositionId The UUID of the automation composition definition * @param automationComposition the automation composition * @return the result of the instantiation operation */ public InstantiationResponse createAutomationComposition(UUID compositionId, - AutomationComposition automationComposition) { - if (!compositionId.equals(automationComposition.getCompositionId())) { - throw new PfModelRuntimeException(Status.BAD_REQUEST, - automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); - } + AutomationComposition automationComposition) { + validateCompositionRequested(compositionId, automationComposition); var checkAutomationCompositionOpt = - automationCompositionProvider.findAutomationComposition(automationComposition.getKey().asIdentifier()); + automationCompositionProvider.findAutomationComposition(automationComposition.getKey().asIdentifier()); if (checkAutomationCompositionOpt.isPresent()) { throw new PfModelRuntimeException(Status.BAD_REQUEST, - automationComposition.getKey().asIdentifier() + " already defined"); + automationComposition.getKey().asIdentifier() + " already defined"); } var validationResult = validateAutomationComposition(automationComposition); @@ -125,18 +122,15 @@ public class AutomationCompositionInstantiationProvider { /** * Update automation composition. * - * @param compositionId The UUID of the automation composition definition + * @param compositionId The UUID of the automation composition definition * @param automationComposition the automation composition * @return the result of the update */ public InstantiationResponse updateAutomationComposition(UUID compositionId, - AutomationComposition automationComposition) { + AutomationComposition automationComposition) { var instanceId = automationComposition.getInstanceId(); var acToUpdate = automationCompositionProvider.getAutomationComposition(instanceId); - if (!compositionId.equals(acToUpdate.getCompositionId())) { - throw new PfModelRuntimeException(Status.BAD_REQUEST, - automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); - } + validateCompositionRequested(compositionId, acToUpdate); if (DeployState.UNDEPLOYED.equals(acToUpdate.getDeployState())) { acToUpdate.setElements(automationComposition.getElements()); acToUpdate.setName(automationComposition.getName()); @@ -166,8 +160,8 @@ public class AutomationCompositionInstantiationProvider { } } var result = acInstanceStateResolver.resolve(deployOrder, LockOrder.NONE, subOrder, - acToUpdate.getDeployState(), acToUpdate.getLockState(), acToUpdate.getSubState(), - acToUpdate.getStateChangeResult()); + acToUpdate.getDeployState(), acToUpdate.getLockState(), acToUpdate.getSubState(), + acToUpdate.getStateChangeResult()); return switch (result) { case "UPDATE" -> updateDeployedAutomationComposition(automationComposition, acToUpdate); @@ -176,7 +170,7 @@ public class AutomationCompositionInstantiationProvider { case "MIGRATE_PRECHECK" -> migratePrecheckAc(automationComposition, acToUpdate); default -> throw new PfModelRuntimeException(Status.BAD_REQUEST, - "Not allowed to " + deployOrder + " in the state " + acToUpdate.getDeployState()); + "Not allowed to " + deployOrder + " in the state " + acToUpdate.getDeployState()); }; } @@ -184,11 +178,13 @@ public class AutomationCompositionInstantiationProvider { * Update deployed AC Element properties. * * @param automationComposition the automation composition - * @param acToBeUpdated the composition to be updated + * @param acToBeUpdated the composition to be updated * @return the result of the update */ private InstantiationResponse updateDeployedAutomationComposition( - AutomationComposition automationComposition, AutomationComposition acToBeUpdated) { + AutomationComposition automationComposition, AutomationComposition acToBeUpdated) { + // save copy in case of a rollback + automationCompositionProvider.copyAcElementsBeforeUpdate(acToBeUpdated); // Iterate and update the element property values for (var element : automationComposition.getElements().entrySet()) { @@ -223,33 +219,11 @@ public class AutomationCompositionInstantiationProvider { throw new PfModelRuntimeException(Status.BAD_REQUEST, "Not allowed to migrate in the state " + acToBeUpdated.getDeployState()); } + // make copy for rollback + automationCompositionProvider.copyAcElementsBeforeUpdate(acToBeUpdated); // Iterate and update the element property values - for (var element : automationComposition.getElements().entrySet()) { - var elementId = element.getKey(); - var dbAcElement = acToBeUpdated.getElements().get(elementId); - // Add additional elements if present for migration - if (dbAcElement == null) { - LOGGER.info("New Ac element {} added in Migration", elementId); - acToBeUpdated.getElements().put(elementId, element.getValue()); - } else { - AcmUtils.recursiveMerge(dbAcElement.getProperties(), element.getValue().getProperties()); - var newDefinition = element.getValue().getDefinition().asConceptKey(); - var dbElementDefinition = dbAcElement.getDefinition().asConceptKey(); - checkCompatibility(newDefinition, dbElementDefinition, automationComposition.getInstanceId()); - dbAcElement.setDefinition(element.getValue().getDefinition()); - } - } - // Remove element which is not present in the new Ac instance - var elementsRemoved = getElementRemoved(acToBeUpdated, automationComposition); - elementsRemoved.forEach(uuid -> acToBeUpdated.getElements().remove(uuid)); - - var validationResult = - validateAutomationComposition(acToBeUpdated, automationComposition.getCompositionTargetId()); - if (!validationResult.isValid()) { - throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); - } - acToBeUpdated.setCompositionTargetId(automationComposition.getCompositionTargetId()); + var elementsRemoved = updateElementsProperties(automationComposition, acToBeUpdated); var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionTargetId()); updateAcForMigration(acToBeUpdated, acDefinition); @@ -281,7 +255,7 @@ public class AutomationCompositionInstantiationProvider { private List getElementRemoved(AutomationComposition acFromDb, AutomationComposition acFromMigration) { return acFromDb.getElements().keySet().stream() - .filter(id -> acFromMigration.getElements().get(id) == null).toList(); + .filter(id -> acFromMigration.getElements().get(id) == null).toList(); } void checkCompatibility(PfConceptKey newDefinition, PfConceptKey dbElementDefinition, @@ -289,46 +263,22 @@ public class AutomationCompositionInstantiationProvider { var compatibility = newDefinition.getCompatibility(dbElementDefinition); if (PfKey.Compatibility.DIFFERENT.equals(compatibility)) { throw new PfModelRuntimeException(Status.BAD_REQUEST, - dbElementDefinition + " is not compatible with " + newDefinition); + dbElementDefinition + " is not compatible with " + newDefinition); } if (PfKey.Compatibility.MAJOR.equals(compatibility) || PfKey.Compatibility.MINOR - .equals(compatibility)) { + .equals(compatibility)) { LOGGER.warn("Migrate {}: Version {} has {} compatibility with {} ", instanceId, newDefinition, - compatibility, dbElementDefinition); + compatibility, dbElementDefinition); } } private InstantiationResponse migratePrecheckAc( - AutomationComposition automationComposition, AutomationComposition acToBeUpdated) { + AutomationComposition automationComposition, AutomationComposition acToBeUpdated) { acToBeUpdated.setPrecheck(true); var copyAc = new AutomationComposition(acToBeUpdated); // Iterate and update the element property values - for (var element : automationComposition.getElements().entrySet()) { - var elementId = element.getKey(); - var copyElement = copyAc.getElements().get(elementId); - // Add additional elements if present for migration - if (copyElement == null) { - LOGGER.info("New Ac element {} added in Migration", elementId); - copyAc.getElements().put(elementId, element.getValue()); - } else { - AcmUtils.recursiveMerge(copyElement.getProperties(), element.getValue().getProperties()); - var newDefinition = element.getValue().getDefinition().asConceptKey(); - var copyElementDefinition = copyElement.getDefinition().asConceptKey(); - checkCompatibility(newDefinition, copyElementDefinition, automationComposition.getInstanceId()); - copyElement.setDefinition(element.getValue().getDefinition()); - } - } - // Remove element which is not present in the new Ac instance - var elementsRemoved = getElementRemoved(copyAc, automationComposition); - elementsRemoved.forEach(uuid -> copyAc.getElements().remove(uuid)); - - var validationResult = - validateAutomationComposition(copyAc, automationComposition.getCompositionTargetId()); - if (!validationResult.isValid()) { - throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); - } - copyAc.setCompositionTargetId(automationComposition.getCompositionTargetId()); + updateElementsProperties(automationComposition, copyAc); // Publish migrate event to the participants supervisionAcHandler.migratePrecheck(copyAc); @@ -348,32 +298,32 @@ public class AutomationCompositionInstantiationProvider { * Validate AutomationComposition. * * @param automationComposition AutomationComposition to validate - * @param compositionId the composition id + * @param compositionId the composition id * @return the result of validation */ private BeanValidationResult validateAutomationComposition(AutomationComposition automationComposition, - UUID compositionId) { + UUID compositionId) { var result = new BeanValidationResult("AutomationComposition", automationComposition); var acDefinitionOpt = acDefinitionProvider.findAcDefinition(compositionId); if (acDefinitionOpt.isEmpty()) { result.addResult(new ObjectValidationResult("ServiceTemplate", compositionId, ValidationStatus.INVALID, - "Commissioned automation composition definition not found")); + "Commissioned automation composition definition not found")); return result; } if (!AcTypeState.PRIMED.equals(acDefinitionOpt.get().getState())) { result.addResult(new ObjectValidationResult("ServiceTemplate.state", acDefinitionOpt.get().getState(), - ValidationStatus.INVALID, "Commissioned automation composition definition not primed")); + ValidationStatus.INVALID, "Commissioned automation composition definition not primed")); return result; } var participantIds = acDefinitionOpt.get().getElementStateMap().values().stream() - .map(NodeTemplateState::getParticipantId).collect(Collectors.toSet()); + .map(NodeTemplateState::getParticipantId).collect(Collectors.toSet()); participantProvider.verifyParticipantState(participantIds); result.addResult(AcmUtils.validateAutomationComposition(automationComposition, - acDefinitionOpt.get().getServiceTemplate(), - acRuntimeParameterGroup.getAcmParameters().getToscaCompositionName())); + acDefinitionOpt.get().getServiceTemplate(), + acRuntimeParameterGroup.getAcmParameters().getToscaCompositionName())); result.addResult(automationCompositionProvider.validateElementIds(automationComposition)); @@ -393,7 +343,7 @@ public class AutomationCompositionInstantiationProvider { if (encryptionUtils.encryptionEnabled()) { var acDefinitionOpt = acDefinitionProvider.findAcDefinition(compositionId); acDefinitionOpt.ifPresent(acDefinition - -> encryptionUtils.findAndEncryptSensitiveData(acDefinition, automationComposition)); + -> encryptionUtils.findAndEncryptSensitiveData(acDefinition, automationComposition)); } } @@ -401,16 +351,16 @@ public class AutomationCompositionInstantiationProvider { * Get Automation Composition. * * @param compositionId The UUID of the automation composition definition - * @param instanceId The UUID of the automation composition instance + * @param instanceId The UUID of the automation composition instance * @return the Automation Composition */ @Transactional(readOnly = true) public AutomationComposition getAutomationComposition(@NonNull UUID compositionId, UUID instanceId) { var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId); if (!compositionId.equals(automationComposition.getCompositionId()) - && !compositionId.equals(automationComposition.getCompositionTargetId())) { + && !compositionId.equals(automationComposition.getCompositionTargetId())) { throw new PfModelRuntimeException(Status.BAD_REQUEST, - automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); + automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); } return automationComposition; } @@ -419,27 +369,20 @@ public class AutomationCompositionInstantiationProvider { * Delete the automation composition with the given name and version. * * @param compositionId The UUID of the automation composition definition - * @param instanceId The UUID of the automation composition instance + * @param instanceId The UUID of the automation composition instance * @return the result of the deletion */ public InstantiationResponse deleteAutomationComposition(UUID compositionId, UUID instanceId) { var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId); - if (!compositionId.equals(automationComposition.getCompositionId())) { - throw new PfModelRuntimeException(Status.BAD_REQUEST, - automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); - } - var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId()); - var participantIds = acDefinition.getElementStateMap().values().stream() - .map(NodeTemplateState::getParticipantId).collect(Collectors.toSet()); - participantProvider.verifyParticipantState(participantIds); + var acDefinition = getAcDefinition(compositionId, automationComposition); var result = acInstanceStateResolver.resolve(DeployOrder.DELETE, - null, null, - automationComposition.getDeployState(), automationComposition.getLockState(), - automationComposition.getSubState(), automationComposition.getStateChangeResult()); + null, null, + automationComposition.getDeployState(), automationComposition.getLockState(), + automationComposition.getSubState(), automationComposition.getStateChangeResult()); if (!DeployOrder.DELETE.name().equals(result)) { var msg = String.format(NOT_VALID_ORDER, DeployOrder.DELETE, - automationComposition.getDeployState(), automationComposition.getLockState(), - automationComposition.getSubState(), automationComposition.getStateChangeResult()); + automationComposition.getDeployState(), automationComposition.getLockState(), + automationComposition.getSubState(), automationComposition.getStateChangeResult()); throw new PfModelRuntimeException(Status.BAD_REQUEST, msg); } supervisionAcHandler.delete(automationComposition, acDefinition); @@ -449,17 +392,18 @@ public class AutomationCompositionInstantiationProvider { /** * Get the requested automation compositions. * - * @param name the name of the automation composition to get, null for all automation compositions - * @param version the version of the automation composition to get, null for all automation compositions + * @param name the name of the automation composition to get, null for all automation compositions + * @param version the version of the automation composition to get, null for all automation compositions * @param pageable the Pageable * @return the automation compositions */ @Transactional(readOnly = true) public AutomationCompositions getAutomationCompositions(@NonNull final UUID compositionId, - final String name, final String version, @NonNull final Pageable pageable) { + final String name, final String version, + @NonNull final Pageable pageable) { var automationCompositions = new AutomationCompositions(); automationCompositions.setAutomationCompositionList( - automationCompositionProvider.getAutomationCompositions(compositionId, name, version, pageable)); + automationCompositionProvider.getAutomationCompositions(compositionId, name, version, pageable)); return automationCompositions; } @@ -467,27 +411,18 @@ public class AutomationCompositionInstantiationProvider { /** * Handle Composition Instance State. * - * @param compositionId the compositionId - * @param instanceId the instanceId + * @param compositionId the compositionId + * @param instanceId the instanceId * @param acInstanceStateUpdate the AcInstanceStateUpdate */ public void compositionInstanceState(UUID compositionId, UUID instanceId, - @Valid AcInstanceStateUpdate acInstanceStateUpdate) { + @Valid AcInstanceStateUpdate acInstanceStateUpdate) { var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId); - if (!compositionId.equals(automationComposition.getCompositionId())) { - throw new PfModelRuntimeException(Status.BAD_REQUEST, - automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); - } - var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId()); - - var participantIds = acDefinition.getElementStateMap().values().stream() - .map(NodeTemplateState::getParticipantId).collect(Collectors.toSet()); - - participantProvider.verifyParticipantState(participantIds); + var acDefinition = getAcDefinition(compositionId, automationComposition); var result = acInstanceStateResolver.resolve(acInstanceStateUpdate.getDeployOrder(), - acInstanceStateUpdate.getLockOrder(), acInstanceStateUpdate.getSubOrder(), - automationComposition.getDeployState(), automationComposition.getLockState(), - automationComposition.getSubState(), automationComposition.getStateChangeResult()); + acInstanceStateUpdate.getLockOrder(), acInstanceStateUpdate.getSubOrder(), + automationComposition.getDeployState(), automationComposition.getLockState(), + automationComposition.getSubState(), automationComposition.getStateChangeResult()); switch (result) { case "DEPLOY": supervisionAcHandler.deploy(automationComposition, acDefinition); @@ -515,9 +450,59 @@ public class AutomationCompositionInstantiationProvider { default: var msg = String.format(NOT_VALID_ORDER, acInstanceStateUpdate, - automationComposition.getDeployState(), automationComposition.getLockState(), - automationComposition.getSubState(), automationComposition.getStateChangeResult()); + automationComposition.getDeployState(), automationComposition.getLockState(), + automationComposition.getSubState(), automationComposition.getStateChangeResult()); throw new PfModelRuntimeException(Status.BAD_REQUEST, msg); } } + + private List updateElementsProperties(AutomationComposition automationComposition, + AutomationComposition acToBeUpdated) { + for (var element : automationComposition.getElements().entrySet()) { + var elementId = element.getKey(); + var dbAcElement = acToBeUpdated.getElements().get(elementId); + // Add additional elements if present for migration + if (dbAcElement == null) { + LOGGER.info("New Ac element {} added in Migration", elementId); + acToBeUpdated.getElements().put(elementId, element.getValue()); + } else { + AcmUtils.recursiveMerge(dbAcElement.getProperties(), element.getValue().getProperties()); + var newDefinition = element.getValue().getDefinition().asConceptKey(); + var dbElementDefinition = dbAcElement.getDefinition().asConceptKey(); + checkCompatibility(newDefinition, dbElementDefinition, automationComposition.getInstanceId()); + dbAcElement.setDefinition(element.getValue().getDefinition()); + } + } + // Remove element which is not present in the new Ac instance + var elementsRemoved = getElementRemoved(acToBeUpdated, automationComposition); + elementsRemoved.forEach(uuid -> acToBeUpdated.getElements().remove(uuid)); + + var validationResult = + validateAutomationComposition(acToBeUpdated, automationComposition.getCompositionTargetId()); + if (!validationResult.isValid()) { + throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); + } + acToBeUpdated.setCompositionTargetId(automationComposition.getCompositionTargetId()); + return elementsRemoved; + } + + private static void validateCompositionRequested(UUID compositionId, + AutomationComposition automationComposition) { + if (!compositionId.equals(automationComposition.getCompositionId())) { + throw new PfModelRuntimeException(Status.BAD_REQUEST, + automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); + } + } + + private AutomationCompositionDefinition getAcDefinition(UUID compositionId, + AutomationComposition automationComposition) { + validateCompositionRequested(compositionId, automationComposition); + var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId()); + + var participantIds = acDefinition.getElementStateMap().values().stream() + .map(NodeTemplateState::getParticipantId).collect(Collectors.toSet()); + + participantProvider.verifyParticipantState(participantIds); + return acDefinition; + } } diff --git a/runtime-acm/src/main/resources/openapi/openapi.yaml b/runtime-acm/src/main/resources/openapi/openapi.yaml index fa8e8b2a1..2bbfe3a83 100644 --- a/runtime-acm/src/main/resources/openapi/openapi.yaml +++ b/runtime-acm/src/main/resources/openapi/openapi.yaml @@ -1,5 +1,5 @@ # ============LICENSE_START======================================================= -# Copyright (C) 2022-2023,2025 OpenInfra Foundation Europe. All rights reserved. +# Copyright (C) 2022-2023, 2025 OpenInfra Foundation Europe. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -33,7 +33,7 @@ servers: description: This value is assigned by the service provider tags: - name: Participant Monitoring - description: Pariticipant Monitoring Controller, for monitoring of and requesting information from participants + description: Participant Monitoring Controller, for monitoring of and requesting information from participants - name: Automation Composition Definition description: Automation Composition Definition Controller, for definition and management of Automation Composition Types - name: Automation Composition Instance @@ -44,7 +44,7 @@ paths: get: tags: - Participant Monitoring - summary: Query Particicpants + summary: Query Participants description: Query the participants that are registered on the ACM runtime operationId: queryParticipants parameters: @@ -146,12 +146,12 @@ paths: security: - basicAuth: [] x-interface info: - api-version: 1.0.0 - last-mod-release: London + api-version: 8.2.1 + last-mod-release: Paris put: tags: - Participant Monitoring - summary: Order an immendiate Participant Report from all participants + summary: Order an immediate Participant Report from all participants description: Requests all participants to immediately generate a heartbeat report with their information and status and the information and status of all their AC Element Types and Instances. The results are published on subsequent GET REST requests on the "participants" endpoint. @@ -226,8 +226,8 @@ paths: security: - basicAuth: [] x-interface info: - api-version: 1.0.0 - last-mod-release: London + api-version: 8.2.1 + last-mod-release: Paris x-codegen-request-body-name: body /participants/{participantId}: get: @@ -235,7 +235,7 @@ paths: - Participant Monitoring summary: Get details of the requested participant definitions - description: Get details of the requested commissioned participant, returning all pariticipant details + description: Get details of the requested commissioned participant, returning all participant details operationId: getParticipant parameters: - name : participantId @@ -341,12 +341,12 @@ paths: security: - basicAuth: [] x-interface info: - api-version: 1.0.0 - last-mod-release: London + api-version: 8.2.1 + last-mod-release: Paris put: tags: - Participant Monitoring - summary: Order an immendiate Participant Report from a participant + summary: Order an immediate Participant Report from a participant description: Requests the participants to immediately generate a heartbeat report with its information and status and the information and status of all its AC Element Types and Instances. The results are published on subsequent GET REST requests on the "participants" endpoint. @@ -444,8 +444,8 @@ paths: security: - basicAuth: [] x-interface info: - api-version: 1.0.0 - last-mod-release: London + api-version: 8.2.1 + last-mod-release: Paris x-codegen-request-body-name: body /compositions: get: @@ -549,8 +549,8 @@ paths: security: - basicAuth: [] x-interface info: - api-version: 1.0.0 - last-mod-release: London + api-version: 8.2.1 + last-mod-release: Paris post: tags: - Automation Composition Definition @@ -657,8 +657,8 @@ paths: security: - basicAuth: [] x-interface info: - api-version: 1.0.0 - last-mod-release: London + api-version: 8.2.1 + last-mod-release: Paris x-codegen-request-body-name: body /compositions/{compositionId}: get: @@ -760,8 +760,8 @@ paths: security: - basicAuth: [] x-interface info: - api-version: 1.0.0 - last-mod-release: London + api-version: 8.2.1 + last-mod-release: Paris put: tags: - Automation Composition Definition @@ -877,8 +877,8 @@ paths: security: - basicAuth: [] x-interface info: - api-version: 1.0.0 - last-mod-release: London + api-version: 8.2.1 + last-mod-release: Paris x-codegen-request-body-name: body delete: tags: @@ -992,8 +992,8 @@ paths: security: - basicAuth: [] x-interface info: - api-version: 1.0.0 - last-mod-release: London + api-version: 8.2.1 + last-mod-release: Paris /compositions/{compositionId}/instances: get: tags: @@ -1116,8 +1116,8 @@ paths: security: - basicAuth: [] x-interface info: - api-version: 1.0.0 - last-mod-release: London + api-version: 8.2.1 + last-mod-release: Paris post: tags: - Automation Composition Instance @@ -1258,8 +1258,8 @@ paths: security: - basicAuth: [] x-interface info: - api-version: 1.0.0 - last-mod-release: London + api-version: 8.2.1 + last-mod-release: Paris x-codegen-request-body-name: body /compositions/{compositionId}/instances/{instanceId}: get: @@ -1365,8 +1365,8 @@ paths: security: - basicAuth: [] x-interface info: - api-version: 1.0.0 - last-mod-release: London + api-version: 8.2.1 + last-mod-release: Paris put: tags: - Automation Composition Instance @@ -1491,8 +1491,8 @@ paths: security: - basicAuth: [] x-interface info: - api-version: 1.0.0 - last-mod-release: London + api-version: 8.2.1 + last-mod-release: Paris x-codegen-request-body-name: body delete: tags: @@ -1613,8 +1613,8 @@ paths: security: - basicAuth: [] x-interface info: - api-version: 1.0.0 - last-mod-release: London + api-version: 8.2.1 + last-mod-release: Paris components: securitySchemes: