From: FrancescoFioraEst Date: Wed, 25 Jun 2025 14:35:05 +0000 (+0100) Subject: Update fetch rollback elements X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=1d3729b0595c1282a0eed1abdb0feba09dda9afa;p=policy%2Fclamp.git Update fetch rollback elements Delete rollback when the instance is deleted. Fix fetch rollback elements from DB. Issue-ID: POLICY-5364 Change-Id: I0b39fc7eda05843799417fb1eb141f462c8e435d Signed-off-by: FrancescoFioraEst --- 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 3d62f91e3..c11d5b89d 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 @@ -40,7 +40,7 @@ public class AutomationCompositionRollback { private UUID compositionId; @NonNull - private Map elements = new LinkedHashMap<>(); + private Map elements = new LinkedHashMap<>(); /** * Copy constructor, does a deep copy. @@ -61,10 +61,6 @@ public class AutomationCompositionRollback { 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)); + this.elements = PfUtils.mapMap(automationComposition.getElements(), UnaryOperator.identity()); } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/AbstractConverter.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/AbstractConverter.java new file mode 100644 index 000000000..c75b32dc0 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/AbstractConverter.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.models.acm.persistence.concepts; + +import jakarta.ws.rs.core.Response; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.base.PfModelRuntimeException; + +public abstract class AbstractConverter { + + private static final Coder coder = new StandardCoder(); + + protected String encode(final T object) { + try { + return object == null ? null : coder.encode(object); + } catch (CoderException e) { + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, e.getMessage(), e); + } + } + + protected T decode(String message, Class clazz) { + try { + return coder.decode(message, clazz); + } catch (CoderException e) { + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, e.getMessage(), e); + } + } + + /** + * Converts an Object to a typed Object. + * + * @param obj the Object + * @param clazz the Class + * @return the object converted + */ + public static T convertObject(Object obj, Class clazz) { + try { + var json = coder.encode(obj); + return coder.decode(json, clazz); + } catch (CoderException e) { + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, e.getMessage(), e); + } + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionRollback.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionRollback.java index 38437e1ee..64b3ccde3 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionRollback.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionRollback.java @@ -33,10 +33,12 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.UUID; import java.util.function.UnaryOperator; +import java.util.stream.Collectors; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NonNull; import org.apache.commons.lang3.ObjectUtils; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionRollback; import org.onap.policy.models.base.PfAuthorative; import org.onap.policy.models.base.PfUtils; @@ -110,7 +112,9 @@ public class JpaAutomationCompositionRollback extends Validated var acmRollback = new AutomationCompositionRollback(); acmRollback.setInstanceId(UUID.fromString(this.instanceId)); acmRollback.setCompositionId(UUID.fromString(this.compositionId)); - acmRollback.setElements(PfUtils.mapMap(this.elements, UnaryOperator.identity())); + acmRollback.setElements(this.elements.values().stream() + .map(el -> AbstractConverter.convertObject(el, AutomationCompositionElement.class)) + .collect(Collectors.toMap(AutomationCompositionElement::getId, UnaryOperator.identity()))); return acmRollback; } @@ -118,7 +122,8 @@ public class JpaAutomationCompositionRollback extends Validated public void fromAuthorative(@NonNull final AutomationCompositionRollback acmRollback) { this.instanceId = acmRollback.getInstanceId().toString(); this.compositionId = acmRollback.getCompositionId().toString(); - this.elements = PfUtils.mapMap(acmRollback.getElements(), UnaryOperator.identity()); + this.elements = acmRollback.getElements().values().stream() + .collect(Collectors.toMap(element -> element.getId().toString(), UnaryOperator.identity())); } @Override diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToDocMessage.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToDocMessage.java index 78eaed245..66aff1e0f 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToDocMessage.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToDocMessage.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2025 Nordix Foundation. + * Copyright (C) 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. @@ -22,25 +22,14 @@ package org.onap.policy.clamp.models.acm.persistence.concepts; import jakarta.persistence.AttributeConverter; import jakarta.persistence.Converter; -import jakarta.ws.rs.core.Response; import org.onap.policy.clamp.models.acm.document.concepts.DocMessage; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.onap.policy.models.base.PfModelRuntimeException; @Converter(autoApply = true) -public class StringToDocMessage implements AttributeConverter { - - private static final Coder coder = new StandardCoder(); +public class StringToDocMessage extends AbstractConverter implements AttributeConverter { @Override public String convertToDatabaseColumn(DocMessage docMessage) { - try { - return docMessage == null ? null : coder.encode(docMessage); - } catch (CoderException e) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, e.getMessage(), e); - } + return encode(docMessage); } @Override @@ -48,10 +37,6 @@ public class StringToDocMessage implements AttributeConverter, String> { - - private static final Coder coder = new StandardCoder(); +public class StringToMapConverter extends AbstractConverter implements AttributeConverter, String> { @Override public String convertToDatabaseColumn(Map map) { - try { - return map == null ? null : coder.encode(map); - } catch (CoderException e) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, e.getMessage(), e); - } + return encode(map); } @SuppressWarnings("unchecked") @@ -50,10 +39,6 @@ public class StringToMapConverter implements AttributeConverter(); } - try { - return coder.decode(dbData, Map.class); - } catch (CoderException e) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, e.getMessage(), e); - } + return decode(dbData, Map.class); } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToServiceTemplateConverter.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToServiceTemplateConverter.java index 01806f564..86a3254fd 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToServiceTemplateConverter.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/StringToServiceTemplateConverter.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. + * Copyright (C) 2021, 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. @@ -22,25 +22,15 @@ package org.onap.policy.clamp.models.acm.persistence.concepts; import jakarta.persistence.AttributeConverter; import jakarta.persistence.Converter; -import jakarta.ws.rs.core.Response; import org.onap.policy.clamp.models.acm.document.concepts.DocToscaServiceTemplate; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.onap.policy.models.base.PfModelRuntimeException; @Converter(autoApply = true) -public class StringToServiceTemplateConverter implements AttributeConverter { - - private static final Coder coder = new StandardCoder(); +public class StringToServiceTemplateConverter extends AbstractConverter + implements AttributeConverter { @Override public String convertToDatabaseColumn(DocToscaServiceTemplate serviceTemplate) { - try { - return serviceTemplate == null ? null : coder.encode(serviceTemplate); - } catch (CoderException e) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, e.getMessage(), e); - } + return encode(serviceTemplate); } @Override @@ -48,10 +38,6 @@ public class StringToServiceTemplateConverter implements AttributeConverter { - - List findByCompositionId(String compositionId); } diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionRollbackTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionRollbackTest.java index a67639dff..ea9eadd31 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionRollbackTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionRollbackTest.java @@ -22,13 +22,9 @@ package org.onap.policy.clamp.models.acm.concepts; import static org.junit.jupiter.api.Assertions.assertEquals; -import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.Map; import java.util.UUID; -import java.util.function.UnaryOperator; import org.junit.jupiter.api.Test; -import org.onap.policy.models.base.PfUtils; class AutomationCompositionRollbackTest { @Test @@ -36,9 +32,7 @@ class AutomationCompositionRollbackTest { var acr0 = new AutomationCompositionRollback(); acr0.setInstanceId(UUID.randomUUID()); acr0.setCompositionId(UUID.randomUUID()); - Map map = new LinkedHashMap<>(); - map.put("test", "test"); - acr0.setElements(PfUtils.mapMap(map, UnaryOperator.identity())); + acr0.setElements(Map.of(UUID.randomUUID(), new AutomationCompositionElement())); var acr1 = new AutomationCompositionRollback(acr0); assertEquals(acr0, acr1); diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/AbstractConverterTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/AbstractConverterTest.java new file mode 100644 index 000000000..5fdcb51de --- /dev/null +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/AbstractConverterTest.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.models.acm.persistence.concepts; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.onap.policy.models.base.PfModelRuntimeException; + +class AbstractConverterTest { + + static class TestConverter extends AbstractConverter { + + } + + @Test + void testNull() { + assertThatThrownBy(() -> AbstractConverter.convertObject("-", Map.class)) + .isInstanceOf(PfModelRuntimeException.class); + + var converter = new TestConverter(); + var dbData = converter.encode(null); + assertThat(dbData).isNull(); + + assertThatThrownBy(() -> converter.decode("-", Map.class)) + .isInstanceOf(PfModelRuntimeException.class); + } + +} 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 94d899e4d..bf91168ff 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 @@ -24,15 +24,12 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.UUID; -import java.util.function.UnaryOperator; import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionRollback; -import org.onap.policy.models.base.PfUtils; - class JpaAutomationCompositionRollbackTest { @@ -96,9 +93,8 @@ class JpaAutomationCompositionRollbackTest { var testAcmRollback = new AutomationCompositionRollback(); testAcmRollback.setInstanceId(UUID.fromString(INSTANCE_ID)); testAcmRollback.setCompositionId(UUID.fromString(COMPOSITION_ID)); - Map map = new HashMap<>(); - map.put("test", "test"); - testAcmRollback.setElements(PfUtils.mapMap(map, UnaryOperator.identity())); + var acElement = new AutomationCompositionElement(); + testAcmRollback.setElements(Map.of(acElement.getId(), acElement)); return testAcmRollback; } 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 dd24833ca..40c26393b 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 @@ -69,33 +69,24 @@ class AutomationCompositionProviderTest { 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"); - - // 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); when(automationCompositionRepository.save(any(JpaAutomationComposition.class))) .thenReturn(inputAutomationCompositionsJpa.get(0)); var inputAc = inputAutomationCompositions.getAutomationCompositionList().get(0); + var automationCompositionProvider = new AutomationCompositionProvider( + automationCompositionRepository, mock(AutomationCompositionElementRepository.class), + mock(AutomationCompositionRollbackRepository.class)); var createdAutomationComposition = automationCompositionProvider.createAutomationComposition(inputAc); inputAc.setInstanceId(createdAutomationComposition.getInstanceId()); inputAc.setLastMsg(createdAutomationComposition.getLastMsg()); @@ -104,6 +95,10 @@ class AutomationCompositionProviderTest { @Test void testAutomationCompositionUpdate() { + var automationCompositionRepository = mock(AutomationCompositionRepository.class); + var automationCompositionProvider = new AutomationCompositionProvider( + automationCompositionRepository, mock(AutomationCompositionElementRepository.class), + mock(AutomationCompositionRollbackRepository.class)); assertThatThrownBy(() -> automationCompositionProvider.updateAutomationComposition(null)) .hasMessageMatching(AC_IS_NULL); @@ -118,6 +113,9 @@ class AutomationCompositionProviderTest { @Test void testGetAutomationCompositionsWithNull() { + var automationCompositionProvider = new AutomationCompositionProvider( + mock(AutomationCompositionRepository.class), mock(AutomationCompositionElementRepository.class), + mock(AutomationCompositionRollbackRepository.class)); assertThatThrownBy(() -> automationCompositionProvider .getAutomationCompositions(UUID.randomUUID(), null, null, null)) .hasMessage("pageable is marked non-null but is null"); @@ -129,6 +127,10 @@ class AutomationCompositionProviderTest { @Test void testGetAutomationCompositions() { + var automationCompositionRepository = mock(AutomationCompositionRepository.class); + var automationCompositionProvider = new AutomationCompositionProvider( + automationCompositionRepository, mock(AutomationCompositionElementRepository.class), + mock(AutomationCompositionRollbackRepository.class)); var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0); when(automationCompositionRepository .findAll(Mockito.any(), any(Pageable.class))) @@ -152,6 +154,10 @@ class AutomationCompositionProviderTest { @Test void testGetAutomationComposition() { var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0); + var automationCompositionRepository = mock(AutomationCompositionRepository.class); + var automationCompositionProvider = new AutomationCompositionProvider( + automationCompositionRepository, mock(AutomationCompositionElementRepository.class), + mock(AutomationCompositionRollbackRepository.class)); assertThatThrownBy( () -> automationCompositionProvider.getAutomationComposition(automationComposition.getInstanceId())) .hasMessageMatching("AutomationComposition not found"); @@ -165,6 +171,10 @@ class AutomationCompositionProviderTest { @Test void testFindAutomationComposition() { var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0); + var automationCompositionRepository = mock(AutomationCompositionRepository.class); + var automationCompositionProvider = new AutomationCompositionProvider( + automationCompositionRepository, mock(AutomationCompositionElementRepository.class), + mock(AutomationCompositionRollbackRepository.class)); var acOpt = automationCompositionProvider.findAutomationComposition(automationComposition.getInstanceId()); assertThat(acOpt).isEmpty(); @@ -185,8 +195,12 @@ class AutomationCompositionProviderTest { @Test void testGetAcInstancesByCompositionId() { var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0); + var automationCompositionRepository = mock(AutomationCompositionRepository.class); when(automationCompositionRepository.findByCompositionId(automationComposition.getCompositionId().toString())) .thenReturn(inputAutomationCompositionsJpa); + var automationCompositionProvider = new AutomationCompositionProvider( + automationCompositionRepository, mock(AutomationCompositionElementRepository.class), + mock(AutomationCompositionRollbackRepository.class)); var acList = automationCompositionProvider.getAcInstancesByCompositionId(automationComposition.getCompositionId()); assertEquals(inputAutomationCompositions.getAutomationCompositionList(), acList); @@ -202,11 +216,15 @@ class AutomationCompositionProviderTest { List res1 = new ArrayList<>(); res1.add(inputAutomationCompositionsJpa.get(0)); + var automationCompositionRepository = mock(AutomationCompositionRepository.class); when(automationCompositionRepository.findByDeployStateIn(List.of(DeployState.DEPLOYING, DeployState.UNDEPLOYING, DeployState.DELETING, DeployState.UPDATING, DeployState.MIGRATING))) .thenReturn(res1); when(automationCompositionRepository.findByLockStateIn(List.of(LockState.LOCKING, LockState.UNLOCKING))) .thenReturn(List.of(inputAutomationCompositionsJpa.get(1))); + var automationCompositionProvider = new AutomationCompositionProvider( + automationCompositionRepository, mock(AutomationCompositionElementRepository.class), + mock(AutomationCompositionRollbackRepository.class)); var acList = automationCompositionProvider.getAcInstancesInTransition(); assertThat(acList).hasSize(2) .contains(inputAutomationCompositions.getAutomationCompositionList().get(0).getInstanceId()) @@ -215,9 +233,17 @@ class AutomationCompositionProviderTest { @Test void testDeleteAutomationComposition() { + var automationCompositionRepository = mock(AutomationCompositionRepository.class); + var acRollbackRepository = mock(AutomationCompositionRollbackRepository.class); + var automationCompositionProvider = new AutomationCompositionProvider( + automationCompositionRepository, mock(AutomationCompositionElementRepository.class), + acRollbackRepository); assertThatThrownBy(() -> automationCompositionProvider.deleteAutomationComposition(UUID.randomUUID())) .hasMessageMatching(".*.failed, automation composition does not exist"); + assertThatThrownBy(() -> automationCompositionProvider.deleteAutomationComposition(null)) + .hasMessageMatching("instanceId is marked non-null but is null"); + var automationComposition = inputAutomationCompositions.getAutomationCompositionList().get(0); when(automationCompositionRepository.findById(automationComposition.getInstanceId().toString())) .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0))); @@ -225,10 +251,22 @@ class AutomationCompositionProviderTest { var deletedAc = automationCompositionProvider.deleteAutomationComposition(automationComposition.getInstanceId()); assertEquals(automationComposition, deletedAc); + + when(acRollbackRepository.existsById(automationComposition.getInstanceId().toString())).thenReturn(true); + + deletedAc = + automationCompositionProvider.deleteAutomationComposition(automationComposition.getInstanceId()); + assertEquals(automationComposition, deletedAc); + verify(acRollbackRepository).deleteById(automationComposition.getInstanceId().toString()); } @Test void testDeleteElementById() { + var automationCompositionRepository = mock(AutomationCompositionRepository.class); + var acElementRepository = mock(AutomationCompositionElementRepository.class); + var automationCompositionProvider = new AutomationCompositionProvider( + automationCompositionRepository, acElementRepository, + mock(AutomationCompositionRollbackRepository.class)); assertThatThrownBy(() -> automationCompositionProvider.deleteAutomationCompositionElement(null)) .hasMessageMatching(ACELEMENT_ID_IS_NULL); var elementId = UUID.randomUUID(); @@ -240,6 +278,10 @@ class AutomationCompositionProviderTest { void testValidateElementIds() { var ac = inputAutomationCompositions.getAutomationCompositionList().get(0); + var acElementRepository = mock(AutomationCompositionElementRepository.class); + var automationCompositionProvider = new AutomationCompositionProvider( + mock(AutomationCompositionRepository.class), acElementRepository, + mock(AutomationCompositionRollbackRepository.class)); var result = automationCompositionProvider.validateElementIds(ac); assertThat(result.isValid()).isTrue(); @@ -265,11 +307,17 @@ class AutomationCompositionProviderTest { @Test void testCopyAcElements() { var ac = inputAutomationCompositions.getAutomationCompositionList().get(0); + var automationCompositionRepository = mock(AutomationCompositionRepository.class); + var acRollbackRepository = mock(AutomationCompositionRollbackRepository.class); + var automationCompositionProvider = new AutomationCompositionProvider( + automationCompositionRepository, mock(AutomationCompositionElementRepository.class), + acRollbackRepository); automationCompositionProvider.copyAcElementsBeforeUpdate(ac); verify(acRollbackRepository).save(any(JpaAutomationCompositionRollback.class)); - assertThrows(PfModelRuntimeException.class, () -> automationCompositionProvider // NOSONAR - .getAutomationCompositionRollback(ac.getInstanceId().toString())); + var instanceId = ac.getInstanceId(); + assertThrows(PfModelRuntimeException.class, () -> automationCompositionProvider + .getAutomationCompositionRollback(instanceId)); } @Test @@ -279,17 +327,25 @@ class AutomationCompositionProviderTest { rollback.setInstanceId(ac.getInstanceId().toString()); rollback.setCompositionId(ac.getCompositionId().toString()); + var acRollbackRepository = mock(AutomationCompositionRollbackRepository.class); when(acRollbackRepository.findById(anyString())).thenReturn(Optional.of(rollback)); - var rbFromDb = automationCompositionProvider.getAutomationCompositionRollback(ac.getInstanceId() - .toString()); + var automationCompositionProvider = new AutomationCompositionProvider( + mock(AutomationCompositionRepository.class), mock(AutomationCompositionElementRepository.class), + acRollbackRepository); + var rbFromDb = automationCompositionProvider.getAutomationCompositionRollback(ac.getInstanceId()); assertNotNull(rbFromDb); } @Test void testGetRollbackEmpty() { + var acRollbackRepository = mock(AutomationCompositionRollbackRepository.class); + var automationCompositionProvider = new AutomationCompositionProvider( + mock(AutomationCompositionRepository.class), mock(AutomationCompositionElementRepository.class), + acRollbackRepository); when(acRollbackRepository.findById(anyString())).thenReturn(Optional.empty()); + var compositionId = UUID.randomUUID(); assertThrows(PfModelRuntimeException.class, () -> automationCompositionProvider - .getAutomationCompositionRollback("empty")); + .getAutomationCompositionRollback(compositionId)); } } 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 14660a812..fdafcf0c5 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 @@ -23,10 +23,9 @@ package org.onap.policy.clamp.acm.runtime.instantiation; import jakarta.validation.Valid; import jakarta.ws.rs.core.Response.Status; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.UUID; +import java.util.function.UnaryOperator; import java.util.stream.Collectors; import lombok.NonNull; import lombok.RequiredArgsConstructor; @@ -463,25 +462,21 @@ public class AutomationCompositionInstantiationProvider { * Rollback AC Instance. * * @param instanceId the instanceId - * @return the instantiation response */ - public InstantiationResponse rollback(UUID instanceId) { + public void rollback(UUID instanceId) { var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId); var automationCompositionToRollback = - automationCompositionProvider.getAutomationCompositionRollback(instanceId.toString()); + automationCompositionProvider.getAutomationCompositionRollback(instanceId); if (DeployState.DEPLOYED.equals(automationComposition.getDeployState()) && SubState.NONE.equals(automationComposition.getSubState()) && StateChangeResult.NO_ERROR.equals(automationComposition.getStateChangeResult())) { - automationComposition.setCompositionId(UUID.fromString(automationCompositionToRollback.getCompositionId())); - Map elements = new HashMap<>(); - automationCompositionToRollback.getElements().forEach((String uuid, Object acElement) -> - elements.put(UUID.fromString(uuid), (AutomationCompositionElement) acElement)); - automationComposition.setElements(elements); + automationComposition.setCompositionId(automationCompositionToRollback.getCompositionId()); + automationComposition.setElements(automationCompositionToRollback.getElements().values().stream() + .collect(Collectors.toMap(AutomationCompositionElement::getId, UnaryOperator.identity()))); automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); AcmUtils.setCascadedState(automationComposition, DeployState.MIGRATION_REVERTING, LockState.LOCKED); automationCompositionProvider.updateAutomationComposition(automationComposition); - return createInstantiationResponse(automationComposition); } else { throw new PfModelRuntimeException(Status.BAD_REQUEST, "Invalid state for rollback"); } diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java index 70d6554f2..a604fd577 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java @@ -27,7 +27,6 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -37,7 +36,6 @@ import static org.onap.policy.clamp.acm.runtime.util.CommonTestData.TOSCA_SERVIC import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.UUID; import org.junit.jupiter.api.BeforeAll; @@ -49,7 +47,6 @@ import org.onap.policy.clamp.acm.runtime.util.CommonTestData; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; -import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; 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.StateChangeResult; @@ -67,7 +64,6 @@ import org.onap.policy.clamp.models.acm.persistence.provider.ProviderUtils; import org.onap.policy.clamp.models.acm.utils.AcmUtils; import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfModelRuntimeException; -import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate; import org.springframework.data.domain.Pageable; @@ -568,8 +564,8 @@ class AutomationCompositionInstantiationProviderTest { var acProvider = mock(AutomationCompositionProvider.class); when(acProvider.getAutomationComposition(automationComposition.getInstanceId())) .thenReturn(automationComposition); - var rollbackRecord = mock(JpaAutomationCompositionRollback.class); - when(acProvider.getAutomationCompositionRollback(anyString())).thenReturn(rollbackRecord); + var rollbackRecord = new JpaAutomationCompositionRollback(); + when(acProvider.getAutomationCompositionRollback(any(UUID.class))).thenReturn(rollbackRecord.toAuthorative()); final var acDefinitionProvider = mock(AcDefinitionProvider.class); final var supervisionAcHandler = mock(SupervisionAcHandler.class); @@ -579,29 +575,26 @@ class AutomationCompositionInstantiationProviderTest { new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, new AcRuntimeParameterGroup(), encryptionUtils); - assertThrows(PfModelRuntimeException.class, () -> instantiationProvider - .rollback(automationComposition.getInstanceId())); + var instanceId = automationComposition.getInstanceId(); + assertThrows(PfModelRuntimeException.class, () -> instantiationProvider.rollback(instanceId)); // DeployState != MIGRATION_REVERTING when(acProvider.getAutomationComposition(automationComposition.getInstanceId())) .thenReturn(automationComposition); - when(acProvider.getAutomationCompositionRollback(anyString())).thenReturn(rollbackRecord); + when(acProvider.getAutomationCompositionRollback(any(UUID.class))).thenReturn(rollbackRecord.toAuthorative()); automationComposition.setDeployState(DeployState.DELETING); - assertThrows(PfModelRuntimeException.class, () -> instantiationProvider - .rollback(automationComposition.getInstanceId())); + assertThrows(PfModelRuntimeException.class, () -> instantiationProvider.rollback(instanceId)); // SubState != NONE automationComposition.setDeployState(DeployState.DEPLOYED); automationComposition.setSubState(SubState.PREPARING); - assertThrows(PfModelRuntimeException.class, () -> instantiationProvider - .rollback(automationComposition.getInstanceId())); + assertThrows(PfModelRuntimeException.class, () -> instantiationProvider.rollback(instanceId)); // StateChangeResult != NO_ERROR automationComposition.setSubState(SubState.NONE); automationComposition.setStateChangeResult(StateChangeResult.FAILED); - assertThrows(PfModelRuntimeException.class, () -> instantiationProvider - .rollback(automationComposition.getInstanceId())); + assertThrows(PfModelRuntimeException.class, () -> instantiationProvider.rollback(instanceId)); verify(acProvider, never()).updateAutomationComposition(any()); } @@ -636,7 +629,7 @@ class AutomationCompositionInstantiationProviderTest { when(acProvider.getAutomationComposition(automationComposition.getInstanceId())) .thenReturn(automationComposition); - when(acProvider.getAutomationCompositionRollback(anyString())).thenReturn(rollbackRecord); + when(acProvider.getAutomationCompositionRollback(any(UUID.class))).thenReturn(rollbackRecord.toAuthorative()); instantiationProvider.rollback(automationComposition.getInstanceId());