diff options
3 files changed, 110 insertions, 35 deletions
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionElementRepository.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionElementRepository.java index 19d791e6c..d0a996e20 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionElementRepository.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionElementRepository.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation. + * Copyright (C) 2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,14 +20,19 @@ package org.onap.policy.clamp.models.acm.persistence.repository; +import jakarta.persistence.LockModeType; import java.util.List; import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionElement; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.repository.query.QueryByExampleExecutor; +import org.springframework.data.jpa.repository.Lock; +import org.springframework.lang.NonNull; -public interface AutomationCompositionElementRepository extends - JpaRepository<JpaAutomationCompositionElement, String>, - QueryByExampleExecutor<JpaAutomationCompositionElement> { +public interface AutomationCompositionElementRepository extends JpaRepository<JpaAutomationCompositionElement, String> { + + @NonNull + @Override + @Lock(LockModeType.PESSIMISTIC_READ) + JpaAutomationCompositionElement getReferenceById(@NonNull String id); List<JpaAutomationCompositionElement> findByParticipantId(String participantId); } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java index 7aa06badb..65ad627d1 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java @@ -287,10 +287,16 @@ public class CacheProvider { */ public Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition, UUID compositionId) { + var definitions = acElementsDefinitions.get(compositionId); Map<UUID, CompositionElementDto> map = new HashMap<>(); for (var element : automationComposition.getElements().values()) { - var compositionInProperties = getCommonProperties(compositionId, element.getDefinition()); - var compositionElement = createCompositionElementDto(compositionId, element, compositionInProperties); + var definition = definitions.get(element.getDefinition()); + var compositionElement = (definition != null) + ? new CompositionElementDto(compositionId, element.getDefinition(), + definition.getAutomationCompositionElementToscaNodeTemplate().getProperties(), + definition.getOutProperties()) : + new CompositionElementDto(compositionId, element.getDefinition(), + Map.of(), Map.of(), ElementState.NOT_PRESENT); map.put(element.getId(), compositionElement); } return map; diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java index 7f21264b2..ec61f886e 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java @@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -216,26 +217,16 @@ class AutomationCompositionHandlerTest { automationComposition.setCompositionId(UUID.randomUUID()); automationComposition.setInstanceId(UUID.randomUUID()); automationComposition.setCompositionTargetId(UUID.randomUUID()); - var cacheProvider = new CacheProvider(CommonTestData.getParticipantParameters()); var definitions = CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition); - cacheProvider.addElementDefinition(automationComposition.getCompositionId(), definitions); - cacheProvider.addElementDefinition(automationComposition.getCompositionTargetId(), definitions); var participantDeploy = - CommonTestData.createparticipantDeploy(cacheProvider.getParticipantId(), automationComposition); - cacheProvider.initializeAutomationComposition(automationComposition.getCompositionId(), - automationComposition.getInstanceId(), participantDeploy); - var migrationMsg = new AutomationCompositionMigration(); - migrationMsg.setStage(0); - migrationMsg.setCompositionId(automationComposition.getCompositionId()); - migrationMsg.setAutomationCompositionId(automationComposition.getInstanceId()); - migrationMsg.setCompositionTargetId(automationComposition.getCompositionTargetId()); - migrationMsg.setParticipantUpdatesList(List.of(participantDeploy)); - var listener = mock(ThreadHandler.class); - var ach = new AutomationCompositionHandler(cacheProvider, mock(ParticipantMessagePublisher.class), listener); - ach.handleAutomationCompositionMigration(migrationMsg); - verify(listener, times(automationComposition.getElements().size())) - .migrate(any(), any(), any(), any(), any(), anyInt()); + CommonTestData.createparticipantDeploy(CommonTestData.getParticipantId(), automationComposition); + + var cacheProvider = createCacheProvider(participantDeploy, automationComposition.getCompositionId(), + automationComposition.getInstanceId(), definitions, + automationComposition.getCompositionTargetId(), definitions); + + testMigration(cacheProvider, automationComposition, 0, automationComposition.getElements().size()); } @Test @@ -243,38 +234,111 @@ class AutomationCompositionHandlerTest { var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); automationComposition.setCompositionId(UUID.randomUUID()); automationComposition.setInstanceId(UUID.randomUUID()); - var cacheProvider = new CacheProvider(CommonTestData.getParticipantParameters()); + + var acMigrate = new AutomationComposition(automationComposition); + acMigrate.setCompositionTargetId(UUID.randomUUID()); + + // replacing first element with new one + var element = acMigrate.getElements().values().iterator().next(); + element.setDefinition(new ToscaConceptIdentifier("policy.clamp.new.element", "1.0.0")); + element.setId(UUID.randomUUID()); + + var migrateDefinitions = + CommonTestData.createAutomationCompositionElementDefinitionList(acMigrate); + + var participantDeploy = + CommonTestData.createparticipantDeploy(CommonTestData.getParticipantId(), automationComposition); var definitions = CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition); - cacheProvider.addElementDefinition(automationComposition.getCompositionId(), definitions); - var participantDeploy = - CommonTestData.createparticipantDeploy(cacheProvider.getParticipantId(), automationComposition); - cacheProvider.initializeAutomationComposition(automationComposition.getCompositionId(), - automationComposition.getInstanceId(), participantDeploy); + var cacheProvider = createCacheProvider(participantDeploy, automationComposition.getCompositionId(), + automationComposition.getInstanceId(), definitions, + acMigrate.getCompositionTargetId(), migrateDefinitions); + + testMigration(cacheProvider, acMigrate, 0, acMigrate.getElements().size() + 1); + } + + @Test + void handleAcMigrationStageTest() { + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + automationComposition.setCompositionId(UUID.randomUUID()); + automationComposition.setInstanceId(UUID.randomUUID()); var acMigrate = new AutomationComposition(automationComposition); acMigrate.setCompositionTargetId(UUID.randomUUID()); // replacing first element with new one var element = acMigrate.getElements().values().iterator().next(); - element.setDefinition(new ToscaConceptIdentifier("policy.clamp.new.element", "1.0.0")); + element.setDefinition(new ToscaConceptIdentifier("policy.clamp.new.element", "1.2.4")); element.setId(UUID.randomUUID()); + // replacing definition version + acMigrate.getElements().values().forEach(el -> el.setDefinition( + new ToscaConceptIdentifier(el.getDefinition().getName(), "1.2.4"))); + var migrateDefinitions = CommonTestData.createAutomationCompositionElementDefinitionList(acMigrate); - cacheProvider.addElementDefinition(acMigrate.getCompositionTargetId(), migrateDefinitions); + migrateDefinitions.forEach(el -> el.getAutomationCompositionElementToscaNodeTemplate() + .setProperties(Map.of("stage", List.of(0, 1)))); + + var participantDeploy = + CommonTestData.createparticipantDeploy(CommonTestData.getParticipantId(), automationComposition); + var definitions = + CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition); + var cacheProvider = createCacheProvider(participantDeploy, automationComposition.getCompositionId(), + automationComposition.getInstanceId(), definitions, + acMigrate.getCompositionTargetId(), migrateDefinitions); + + // scenario 1,2 + migrateDefinitions.forEach(el -> el.getAutomationCompositionElementToscaNodeTemplate() + .setProperties(Map.of("stage", List.of(1, 2)))); + + // expected the element deleted + testMigration(cacheProvider, acMigrate, 0, 1); + + // expected 4 elements from stage 1 + testMigration(cacheProvider, acMigrate, 1, 4); + + // scenario 0,2 + cacheProvider = createCacheProvider(participantDeploy, automationComposition.getCompositionId(), + automationComposition.getInstanceId(), definitions, + acMigrate.getCompositionTargetId(), migrateDefinitions); + + migrateDefinitions.forEach(el -> el.getAutomationCompositionElementToscaNodeTemplate() + .setProperties(Map.of("stage", List.of(0, 2)))); + + // expected the element deleted + 4 elements from stage 0 + testMigration(cacheProvider, acMigrate, 0, 5); + + // expected 0 elements + testMigration(cacheProvider, acMigrate, 1, 0); + } + + private CacheProvider createCacheProvider(ParticipantDeploy participantDeploy, + UUID compositionId, UUID instanceId, List<AutomationCompositionElementDefinition> definitions, + UUID compositionTargetId, List<AutomationCompositionElementDefinition> migrateDefinitions) { + var cacheProvider = new CacheProvider(CommonTestData.getParticipantParameters()); + cacheProvider.addElementDefinition(compositionId, definitions); + cacheProvider.initializeAutomationComposition(compositionId, instanceId, participantDeploy); + cacheProvider.addElementDefinition(compositionTargetId, migrateDefinitions); + return cacheProvider; + } + + private void testMigration(CacheProvider cacheProvider, AutomationComposition acMigrate, + int stage, int expectedMigrated) { var migrationMsg = new AutomationCompositionMigration(); - migrationMsg.setStage(0); + migrationMsg.setStage(stage); migrationMsg.setCompositionId(acMigrate.getCompositionId()); migrationMsg.setAutomationCompositionId(acMigrate.getInstanceId()); migrationMsg.setCompositionTargetId(acMigrate.getCompositionTargetId()); var participantMigrate = CommonTestData.createparticipantDeploy(cacheProvider.getParticipantId(), acMigrate); migrationMsg.setParticipantUpdatesList(List.of(participantMigrate)); var listener = mock(ThreadHandler.class); + + clearInvocations(); var ach = new AutomationCompositionHandler(cacheProvider, mock(ParticipantMessagePublisher.class), listener); ach.handleAutomationCompositionMigration(migrationMsg); - verify(listener, times(acMigrate.getElements().size() + 1)) - .migrate(any(), any(), any(), any(), any(), anyInt()); + verify(listener, times(expectedMigrated)).migrate(any(), any(), any(), any(), any(), anyInt()); } + } |