aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrancescoFioraEst <francesco.fiora@est.tech>2024-01-11 13:00:26 +0000
committerFrancescoFioraEst <francesco.fiora@est.tech>2024-03-27 17:06:02 +0000
commita2c5d07a5a65cb37b82a20f6756470c315e90ff8 (patch)
tree6a98b5961e986b91203b46a5f0418e3057432b49
parentb7291f81e63c5d4e30351ed0429167937934bc71 (diff)
Allow element version update in migration
Allow composition definition element to update the version in migration. Issue-ID: POLICY-4950 Change-Id: I40d2a4fea2178a3daf00c57861ce30e231cccb1a Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java104
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java40
2 files changed, 109 insertions, 35 deletions
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 84920dd03..75b9e8619 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
@@ -26,8 +26,8 @@ import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import java.util.UUID;
import java.util.stream.Collectors;
-import lombok.AllArgsConstructor;
import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup;
import org.onap.policy.clamp.acm.runtime.participants.AcmParticipantProvider;
import org.onap.policy.clamp.acm.runtime.supervision.SupervisionAcHandler;
@@ -47,7 +47,10 @@ import org.onap.policy.clamp.models.acm.utils.AcmUtils;
import org.onap.policy.common.parameters.BeanValidationResult;
import org.onap.policy.common.parameters.ObjectValidationResult;
import org.onap.policy.common.parameters.ValidationStatus;
+import org.onap.policy.models.base.PfKey;
import org.onap.policy.models.base.PfModelRuntimeException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -56,10 +59,12 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Service
@Transactional
-@AllArgsConstructor
+@RequiredArgsConstructor
public class AutomationCompositionInstantiationProvider {
private static final String DO_NOT_MATCH = " do not match with ";
+ private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionInstantiationProvider.class);
+
private final AutomationCompositionProvider automationCompositionProvider;
private final AcDefinitionProvider acDefinitionProvider;
private final AcInstanceStateResolver acInstanceStateResolver;
@@ -93,10 +98,13 @@ public class AutomationCompositionInstantiationProvider {
}
automationComposition = automationCompositionProvider.createAutomationComposition(automationComposition);
+ return createInstantiationResponse(automationComposition);
+ }
+
+ private InstantiationResponse createInstantiationResponse(AutomationComposition automationComposition) {
var response = new InstantiationResponse();
response.setInstanceId(automationComposition.getInstanceId());
response.setAffectedAutomationComposition(automationComposition.getKey().asIdentifier());
-
return response;
}
@@ -109,7 +117,6 @@ public class AutomationCompositionInstantiationProvider {
*/
public InstantiationResponse updateAutomationComposition(UUID compositionId,
AutomationComposition automationComposition) {
- var response = new InstantiationResponse();
var instanceId = automationComposition.getInstanceId();
var acToUpdate = automationCompositionProvider.getAutomationComposition(instanceId);
if (!compositionId.equals(acToUpdate.getCompositionId())) {
@@ -127,14 +134,16 @@ public class AutomationCompositionInstantiationProvider {
throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
}
automationComposition = automationCompositionProvider.updateAutomationComposition(acToUpdate);
- response.setInstanceId(instanceId);
- response.setAffectedAutomationComposition(automationComposition.getKey().asIdentifier());
- return response;
+ return createInstantiationResponse(automationComposition);
} else if ((DeployState.DEPLOYED.equals(acToUpdate.getDeployState())
|| DeployState.UPDATING.equals(acToUpdate.getDeployState()))
&& LockState.LOCKED.equals(acToUpdate.getLockState())) {
- return updateDeployedAutomationComposition(automationComposition, acToUpdate);
+ if (automationComposition.getCompositionTargetId() != null) {
+ return migrateAutomationComposition(automationComposition, acToUpdate);
+ } else {
+ return updateDeployedAutomationComposition(automationComposition, acToUpdate);
+ }
}
throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
"Not allowed to update in the state " + acToUpdate.getDeployState());
@@ -147,15 +156,9 @@ public class AutomationCompositionInstantiationProvider {
* @param acToBeUpdated the composition to be updated
* @return the result of the update
*/
- public InstantiationResponse updateDeployedAutomationComposition(
+ private InstantiationResponse updateDeployedAutomationComposition(
AutomationComposition automationComposition, AutomationComposition acToBeUpdated) {
- if (automationComposition.getCompositionTargetId() != null
- && !DeployState.DEPLOYED.equals(acToBeUpdated.getDeployState())) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
- "Not allowed to migrate in the state " + acToBeUpdated.getDeployState());
- }
-
// Iterate and update the element property values
for (var element : automationComposition.getElements().entrySet()) {
var elementId = element.getKey();
@@ -169,31 +172,62 @@ public class AutomationCompositionInstantiationProvider {
throw new PfModelRuntimeException(Status.BAD_REQUEST, "There is a restarting process, Update not allowed");
}
- if (automationComposition.getCompositionTargetId() != null) {
- var validationResult =
- validateAutomationComposition(acToBeUpdated, automationComposition.getCompositionTargetId());
- if (!validationResult.isValid()) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
- }
- acToBeUpdated.setCompositionTargetId(automationComposition.getCompositionTargetId());
+ var validationResult = validateAutomationComposition(acToBeUpdated);
+ if (!validationResult.isValid()) {
+ throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
+ }
+ // Publish property update event to the participants
+ supervisionAcHandler.update(acToBeUpdated);
- // Publish migrate event to the participants
- supervisionAcHandler.migrate(acToBeUpdated, automationComposition.getCompositionTargetId());
- } else {
- var validationResult = validateAutomationComposition(acToBeUpdated);
- if (!validationResult.isValid()) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
+ automationComposition = automationCompositionProvider.updateAutomationComposition(acToBeUpdated);
+ return createInstantiationResponse(automationComposition);
+ }
+
+ private InstantiationResponse migrateAutomationComposition(
+ AutomationComposition automationComposition, AutomationComposition acToBeUpdated) {
+
+ if (!DeployState.DEPLOYED.equals(acToBeUpdated.getDeployState())) {
+ throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
+ "Not allowed to migrate in the state " + acToBeUpdated.getDeployState());
+ }
+ if (automationComposition.getRestarting() != null) {
+ throw new PfModelRuntimeException(Status.BAD_REQUEST, "There is a restarting process, Migrate not allowed");
+ }
+
+ // Iterate and update the element property values
+ for (var element : automationComposition.getElements().entrySet()) {
+ var elementId = element.getKey();
+ var dbAcElement = acToBeUpdated.getElements().get(elementId);
+ if (dbAcElement == null) {
+ throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, "Element id not present " + elementId);
+ }
+ dbAcElement.getProperties().putAll(element.getValue().getProperties());
+ var newDefinition = element.getValue().getDefinition();
+ var compatibility =
+ newDefinition.asConceptKey().getCompatibility(dbAcElement.getDefinition().asConceptKey());
+ if (PfKey.Compatibility.DIFFERENT.equals(compatibility)) {
+ throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
+ dbAcElement.getDefinition() + " is not compatible with " + newDefinition);
+ }
+ if (PfKey.Compatibility.MAJOR.equals(compatibility) || PfKey.Compatibility.MINOR.equals(compatibility)) {
+ LOGGER.warn("Migrate {}: Version {} has {} compatibility with {} ",
+ automationComposition.getInstanceId(), newDefinition, compatibility, dbAcElement.getDefinition());
}
- // Publish property update event to the participants
- supervisionAcHandler.update(acToBeUpdated);
+ dbAcElement.setDefinition(element.getValue().getDefinition());
+ }
+
+ var validationResult =
+ validateAutomationComposition(acToBeUpdated, automationComposition.getCompositionTargetId());
+ if (!validationResult.isValid()) {
+ throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
}
+ acToBeUpdated.setCompositionTargetId(automationComposition.getCompositionTargetId());
+
+ // Publish migrate event to the participants
+ supervisionAcHandler.migrate(acToBeUpdated, automationComposition.getCompositionTargetId());
automationComposition = automationCompositionProvider.updateAutomationComposition(acToBeUpdated);
- var response = new InstantiationResponse();
- var instanceId = automationComposition.getInstanceId();
- response.setInstanceId(instanceId);
- response.setAffectedAutomationComposition(automationComposition.getKey().asIdentifier());
- return response;
+ return createInstantiationResponse(automationComposition);
}
private BeanValidationResult validateAutomationComposition(AutomationComposition automationComposition) {
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 87bfe1b38..fbd8330fc 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
@@ -240,6 +240,11 @@ class AutomationCompositionInstantiationProviderTest {
() -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
.hasMessageMatching("There is a restarting process, Update not allowed");
+ automationCompositionUpdate.setCompositionTargetId(UUID.randomUUID());
+ assertThatThrownBy(
+ () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
+ .hasMessageMatching("There is a restarting process, Migrate not allowed");
+
automationCompositionUpdate.setDeployState(DeployState.UNDEPLOYED);
automationCompositionUpdate.setLockState(LockState.NONE);
@@ -322,6 +327,41 @@ class AutomationCompositionInstantiationProviderTest {
}
@Test
+ void testMigrateBadRequest() {
+ var acDefinitionProvider = mock(AcDefinitionProvider.class);
+ var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
+ var compositionId = acDefinition.getCompositionId();
+ when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
+
+ var automationComposition =
+ InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
+ automationComposition.setCompositionId(compositionId);
+ automationComposition.setDeployState(DeployState.DEPLOYED);
+ automationComposition.setLockState(LockState.LOCKED);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
+ .thenReturn(automationComposition);
+ when(acProvider.updateAutomationComposition(automationComposition)).thenReturn(automationComposition);
+
+ var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
+ var compositionTargetId = acDefinitionTarget.getCompositionId();
+ when(acDefinitionProvider.findAcDefinition(compositionTargetId)).thenReturn(Optional.of(acDefinitionTarget));
+
+ var acMigrate = new AutomationComposition(automationComposition);
+ acMigrate.setCompositionTargetId(compositionTargetId);
+ automationComposition.getElements().clear();
+
+ var supervisionAcHandler = mock(SupervisionAcHandler.class);
+ var acmParticipantProvider = mock(AcmParticipantProvider.class);
+ var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
+ null, supervisionAcHandler, acmParticipantProvider, new AcRuntimeParameterGroup());
+
+ assertThatThrownBy(() -> instantiationProvider
+ .updateAutomationComposition(automationComposition.getCompositionId(), acMigrate))
+ .hasMessageStartingWith("Element id not present");
+ }
+
+ @Test
void testInstantiationDelete() {
var automationComposition =
InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Delete");