From 7f7d2bfe1673f3334e43029bb81408d3305fa2e2 Mon Sep 17 00:00:00 2001 From: FrancescoFioraEst Date: Mon, 16 Oct 2023 12:57:37 +0100 Subject: Fix messages in ACM Fix TIMEOUT support in MIGRATING. Avoid conflicts updating AC instance Element instead of a full AC instance. Using ExecutorService to send messages to the participant, the transaction will completed before the message is sent. Issue-ID: POLICY-4811 Change-Id: I2730ae694c8a5c9edfe500b1fa93cfb3787f32c5 Signed-off-by: FrancescoFioraEst --- .../provider/AcInstanceStateResolver.java | 7 ++++--- .../provider/AutomationCompositionProvider.java | 18 +++++++++++++++++- .../acm/persistence/provider/ProviderUtils.java | 17 ++++++++++++++--- .../policy/clamp/models/acm/utils/AcmUtils.java | 1 + .../provider/AutomationCompositionProviderTest.java | 21 +++++++++++++++++++-- 5 files changed, 55 insertions(+), 9 deletions(-) (limited to 'models/src') diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolver.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolver.java index 7fed8a756..ace246c5d 100755 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolver.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolver.java @@ -95,10 +95,11 @@ public class AcInstanceStateResolver { // timeout this.graph.put(new String[] {DEPLOY, LOCK_NONE, UNDEPLOYING, STATE_LOCKED_NONE, TIMEOUT}, DEPLOY); - this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, UNDEPLOYING, STATE_LOCKED_NONE, TIMEOUT}, UNDEPLOY); - this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, UPDATING, STATE_LOCKED_NONE, TIMEOUT}, UNDEPLOY); - this.graph.put(new String[] {DEPLOY, LOCK_NONE, DEPLOYING, STATE_LOCKED_NONE, TIMEOUT}, DEPLOY); + + this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, UNDEPLOYING, STATE_LOCKED_NONE, TIMEOUT}, UNDEPLOY); + this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, UPDATING, LOCKED, TIMEOUT}, UNDEPLOY); + this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, MIGRATING, LOCKED, TIMEOUT}, UNDEPLOY); this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, DEPLOYING, STATE_LOCKED_NONE, TIMEOUT}, UNDEPLOY); this.graph.put(new String[] {DELETE, LOCK_NONE, DELETING, LOCK_NONE, TIMEOUT}, DELETE); 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 6ff8d8432..6b90619c9 100755 --- 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 @@ -31,6 +31,7 @@ import java.util.UUID; 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.AutomationCompositionInfo; import org.onap.policy.clamp.models.acm.concepts.DeployState; import org.onap.policy.clamp.models.acm.concepts.LockState; @@ -43,6 +44,7 @@ import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.springframework.data.domain.Example; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** @@ -77,7 +79,7 @@ public class AutomationCompositionProvider { * @param instanceId the ID of the automation composition to get * @return the automation composition found */ - @Transactional(readOnly = true) + @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public Optional findAutomationComposition(final UUID instanceId) { var result = automationCompositionRepository.findById(instanceId.toString()); return result.stream().map(JpaAutomationComposition::toAuthorative).findFirst(); @@ -209,4 +211,18 @@ public class AutomationCompositionProvider { } acElementRepository.saveAll(jpaList); } + + /** + * Update AutomationCompositionElement. + * + * @param element the AutomationCompositionElement + * @param instanceId the instance Id + */ + public void updateAutomationCompositionElement(@NonNull final AutomationCompositionElement element, + @NonNull final UUID instanceId) { + var jpaAcElement = new JpaAutomationCompositionElement(element.getId().toString(), instanceId.toString()); + jpaAcElement.fromAuthorative(element); + ProviderUtils.validate(element, jpaAcElement, "AutomationCompositionElement"); + acElementRepository.save(jpaAcElement); + } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ProviderUtils.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ProviderUtils.java index 6ba6ac016..6feb2b719 100755 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ProviderUtils.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/ProviderUtils.java @@ -72,17 +72,28 @@ public final class ProviderUtils { */ public static > J getJpaAndValidate(A authorativeConcept, Supplier jpaSupplier, String conceptDescription) { - var validationResult = new BeanValidationResult(conceptDescription, authorativeConcept); - var jpaConcept = jpaSupplier.get(); jpaConcept.fromAuthorative(authorativeConcept); + validate(authorativeConcept, jpaConcept, conceptDescription); + return jpaConcept; + } + + /** + * Validate a Jpa object. + * + * @param authorativeConcept the concept + * @param jpaConcept the Jpa of the concept + * @param conceptDescription the description used for validation result + */ + public static > void validate(A authorativeConcept, + J jpaConcept, String conceptDescription) { + var validationResult = new BeanValidationResult(conceptDescription, authorativeConcept); validationResult.addResult(jpaConcept.validate(conceptDescription)); if (!validationResult.isValid()) { throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult()); } - return jpaConcept; } /** diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java index c3d8fc4a4..0fd7ab95c 100755 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java @@ -381,6 +381,7 @@ public final class AcmUtils { for (var element : automationComposition.getElements().values()) { element.setDeployState(deployState); element.setLockState(lockState); + element.setMessage(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 0991c1bd0..e7ceab830 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 @@ -25,6 +25,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.List; @@ -44,7 +45,8 @@ import org.springframework.data.domain.Example; class AutomationCompositionProviderTest { - private static final String OBJECT_IS_NULL = "automationComposition is marked non-null but is null"; + private static final String AC_IS_NULL = "automationComposition is marked non-null but is null"; + private static final String ACELEMENT_IS_NULL = "element is marked non-null but is null"; private static final Coder CODER = new StandardCoder(); private static final String AUTOMATION_COMPOSITION_JSON = @@ -84,7 +86,7 @@ class AutomationCompositionProviderTest { mock(AutomationCompositionElementRepository.class)); assertThatThrownBy(() -> automationCompositionProvider.updateAutomationComposition(null)) - .hasMessageMatching(OBJECT_IS_NULL); + .hasMessageMatching(AC_IS_NULL); when(automationCompositionRepository.save(inputAutomationCompositionsJpa.get(0))) .thenReturn(inputAutomationCompositionsJpa.get(0)); @@ -185,4 +187,19 @@ class AutomationCompositionProviderTest { automationCompositionProvider.deleteAutomationComposition(automationComposition.getInstanceId()); assertEquals(automationComposition, deletedAc); } + + @Test + void testAutomationCompositionElementUpdate() { + var acElementRepository = mock(AutomationCompositionElementRepository.class); + var automationCompositionProvider = new AutomationCompositionProvider( + mock(AutomationCompositionRepository.class), acElementRepository); + + assertThatThrownBy(() -> automationCompositionProvider.updateAutomationCompositionElement(null, null)) + .hasMessageMatching(ACELEMENT_IS_NULL); + + var acElement = inputAutomationCompositions.getAutomationCompositionList().get(0).getElements().values() + .iterator().next(); + automationCompositionProvider.updateAutomationCompositionElement(acElement, UUID.randomUUID()); + verify(acElementRepository).save(any()); + } } -- cgit 1.2.3-korg