aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java8
-rw-r--r--models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java27
-rw-r--r--models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java4
-rw-r--r--models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionTest.java32
-rw-r--r--models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProviderTest.java1
-rw-r--r--models/src/test/resources/providers/TestAutomationCompositions.json2
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java15
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java106
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/TimeoutHandler.java87
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java12
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java30
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/TimeoutHandlerTest.java67
12 files changed, 158 insertions, 233 deletions
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java
index 0cf1f99ec..eb5b6dc9b 100644
--- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java
@@ -1,6 +1,6 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2023 Nordix Foundation.
+ * Copyright (C) 2021-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.
@@ -52,6 +52,10 @@ public class AutomationComposition extends ToscaEntity implements Comparable<Aut
@NonNull
private LockState lockState = LockState.NONE;
+ private String lastMsg;
+
+ private Integer phase;
+
private Map<UUID, AutomationCompositionElement> elements;
private StateChangeResult stateChangeResult;
@@ -69,6 +73,8 @@ public class AutomationComposition extends ToscaEntity implements Comparable<Aut
this.restarting = otherAutomationComposition.restarting;
this.deployState = otherAutomationComposition.deployState;
this.lockState = otherAutomationComposition.lockState;
+ this.lastMsg = otherAutomationComposition.lastMsg;
+ this.phase = otherAutomationComposition.phase;
this.elements = PfUtils.mapMap(otherAutomationComposition.elements, AutomationCompositionElement::new);
this.stateChangeResult = otherAutomationComposition.stateChangeResult;
}
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java
index 5e27fde53..0bf6a9e1a 100644
--- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java
@@ -1,6 +1,6 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2023 Nordix Foundation.
+ * Copyright (C) 2021-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.
@@ -32,6 +32,7 @@ import jakarta.persistence.InheritanceType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
+import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
@@ -44,6 +45,7 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
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;
+import org.onap.policy.clamp.models.acm.utils.TimestampHelper;
import org.onap.policy.common.parameters.annotations.NotNull;
import org.onap.policy.common.parameters.annotations.Valid;
import org.onap.policy.models.base.PfAuthorative;
@@ -98,6 +100,13 @@ public class JpaAutomationComposition extends Validated
private StateChangeResult stateChangeResult;
@Column
+ @NotNull
+ private Timestamp lastMsg;
+
+ @Column
+ private Integer phase;
+
+ @Column
private String description;
@NotNull
@@ -149,6 +158,8 @@ public class JpaAutomationComposition extends Validated
this.restarting = copyConcept.restarting;
this.deployState = copyConcept.deployState;
this.lockState = copyConcept.lockState;
+ this.lastMsg = copyConcept.lastMsg;
+ this.phase = copyConcept.phase;
this.description = copyConcept.description;
this.stateChangeResult = copyConcept.stateChangeResult;
this.elements = PfUtils.mapList(copyConcept.elements, JpaAutomationCompositionElement::new);
@@ -177,6 +188,8 @@ public class JpaAutomationComposition extends Validated
automationComposition.setRestarting(restarting);
automationComposition.setDeployState(deployState);
automationComposition.setLockState(lockState);
+ automationComposition.setLastMsg(lastMsg.toString());
+ automationComposition.setPhase(phase);
automationComposition.setDescription(description);
automationComposition.setStateChangeResult(stateChangeResult);
automationComposition.setElements(new LinkedHashMap<>(this.elements.size()));
@@ -199,6 +212,8 @@ public class JpaAutomationComposition extends Validated
this.restarting = automationComposition.getRestarting();
this.deployState = automationComposition.getDeployState();
this.lockState = automationComposition.getLockState();
+ this.lastMsg = TimestampHelper.toTimestamp(automationComposition.getLastMsg());
+ this.phase = automationComposition.getPhase();
this.description = automationComposition.getDescription();
this.stateChangeResult = automationComposition.getStateChangeResult();
this.elements = new ArrayList<>(automationComposition.getElements().size());
@@ -229,6 +244,16 @@ public class JpaAutomationComposition extends Validated
return result;
}
+ result = lastMsg.compareTo(other.lastMsg);
+ if (result != 0) {
+ return result;
+ }
+
+ result = ObjectUtils.compare(phase, other.phase);
+ if (result != 0) {
+ return result;
+ }
+
result = ObjectUtils.compare(version, other.version);
if (result != 0) {
return result;
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 0293bd3c5..5f523ad27 100644
--- 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
@@ -29,7 +29,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.Queue;
import java.util.UUID;
import java.util.function.Function;
import java.util.function.UnaryOperator;
@@ -71,7 +70,7 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class AcmUtils {
public static final String ENTRY = "entry ";
- private static StringToMapConverter MAP_CONVERTER = new StringToMapConverter();
+ private static final StringToMapConverter MAP_CONVERTER = new StringToMapConverter();
/**
* Get the Policy information in the service template for the deploy message to participants.
@@ -379,6 +378,7 @@ public final class AcmUtils {
final DeployState deployState, final LockState lockState) {
automationComposition.setDeployState(deployState);
automationComposition.setLockState(lockState);
+ automationComposition.setLastMsg(TimestampHelper.now());
if (MapUtils.isEmpty(automationComposition.getElements())) {
return;
diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionTest.java
index 66554e7ec..b56e77801 100644
--- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionTest.java
+++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionTest.java
@@ -1,6 +1,6 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2023 Nordix Foundation.
+ * Copyright (C) 2021-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.
@@ -27,6 +27,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import java.sql.Timestamp;
+import java.time.Instant;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.UUID;
@@ -35,6 +37,7 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
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;
+import org.onap.policy.clamp.models.acm.utils.TimestampHelper;
import org.onap.policy.models.base.PfConceptKey;
/**
@@ -93,9 +96,9 @@ class JpaAutomationCompositionTest {
@Test
void testJpaAutomationComposition() {
- var jpaAutomationComposition = createJpaAutomationCompositionInstance();
-
var automationComposition = createAutomationCompositionInstance();
+ var jpaAutomationComposition = new JpaAutomationComposition(automationComposition);
+
assertEquals(automationComposition, jpaAutomationComposition.toAuthorative());
var target = UUID.randomUUID();
@@ -125,7 +128,7 @@ class JpaAutomationCompositionTest {
@Test
void testJpaAutomationCompositionValidation() {
- var testJpaAutomationComposition = createJpaAutomationCompositionInstance();
+ var testJpaAutomationComposition = new JpaAutomationComposition(createAutomationCompositionInstance());
assertThatThrownBy(() -> testJpaAutomationComposition.validate(null))
.hasMessageMatching("fieldName is marked .*ull but is null");
@@ -135,7 +138,7 @@ class JpaAutomationCompositionTest {
@Test
void testJpaAutomationCompositionCompareTo() {
- var jpaAutomationComposition = createJpaAutomationCompositionInstance();
+ var jpaAutomationComposition = new JpaAutomationComposition(createAutomationCompositionInstance());
var otherJpaAutomationComposition = new JpaAutomationComposition(jpaAutomationComposition);
assertEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition));
@@ -168,6 +171,16 @@ class JpaAutomationCompositionTest {
jpaAutomationComposition.setVersion("0.0.1");
assertEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition));
+ jpaAutomationComposition.setLastMsg(Timestamp.from(Instant.EPOCH));
+ assertNotEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition));
+ jpaAutomationComposition.setLastMsg(otherJpaAutomationComposition.getLastMsg());
+ assertEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition));
+
+ jpaAutomationComposition.setPhase(0);
+ assertNotEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition));
+ jpaAutomationComposition.setPhase(null);
+ assertEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition));
+
jpaAutomationComposition.setDeployState(DeployState.DEPLOYED);
assertNotEquals(0, jpaAutomationComposition.compareTo(otherJpaAutomationComposition));
jpaAutomationComposition.setDeployState(DeployState.UNDEPLOYED);
@@ -225,19 +238,12 @@ class JpaAutomationCompositionTest {
assertEquals(ac2, ac0);
}
- private JpaAutomationComposition createJpaAutomationCompositionInstance() {
- var testAutomationComposition = createAutomationCompositionInstance();
- var testJpaAutomationComposition = new JpaAutomationComposition();
- testJpaAutomationComposition.fromAuthorative(testAutomationComposition);
-
- return testJpaAutomationComposition;
- }
-
private AutomationComposition createAutomationCompositionInstance() {
var testAutomationComposition = new AutomationComposition();
testAutomationComposition.setName("automation-composition");
testAutomationComposition.setInstanceId(UUID.fromString(INSTANCE_ID));
testAutomationComposition.setVersion("0.0.1");
+ testAutomationComposition.setLastMsg(TimestampHelper.now());
testAutomationComposition.setCompositionId(UUID.fromString(COMPOSITION_ID));
testAutomationComposition.setElements(new LinkedHashMap<>());
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 463e958f3..8e7e50de7 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
@@ -85,6 +85,7 @@ class AutomationCompositionProviderTest {
var createdAutomationComposition = automationCompositionProvider.createAutomationComposition(inputAc);
inputAc.setInstanceId(createdAutomationComposition.getInstanceId());
+ inputAc.setLastMsg(createdAutomationComposition.getLastMsg());
assertEquals(inputAc, createdAutomationComposition);
}
diff --git a/models/src/test/resources/providers/TestAutomationCompositions.json b/models/src/test/resources/providers/TestAutomationCompositions.json
index 24f5a4870..c75337bc1 100644
--- a/models/src/test/resources/providers/TestAutomationCompositions.json
+++ b/models/src/test/resources/providers/TestAutomationCompositions.json
@@ -5,6 +5,7 @@
"instanceId": "809c62b3-8918-41b9-a748-e21eb79c6c89",
"deployState": "UNDEPLOYED",
"lockState": "NONE",
+ "lastMsg": "2024-05-22 10:04:37.6020187",
"elements": {
"709c62b3-8918-41b9-a747-e21eb79c6c20": {
"id": "709c62b3-8918-41b9-a747-e21eb79c6c20",
@@ -56,6 +57,7 @@
"instanceId": "809c62b3-8918-41b9-a748-e21eb79c6c90",
"deployState": "UNDEPLOYED",
"lockState": "NONE",
+ "lastMsg": "2024-05-22 10:04:37.6020187",
"elements": {
"709c62b3-8918-41b9-a747-e21eb79c6c24": {
"id": "709c62b3-8918-41b9-a747-e21eb79c6c24",
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java
index d6fa5d8d7..802c6603b 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java
@@ -86,8 +86,9 @@ public class SupervisionAcHandler {
AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYING, LockState.NONE);
}
automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
- automationCompositionProvider.updateAutomationComposition(automationComposition);
var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate());
+ automationComposition.setPhase(startPhase);
+ automationCompositionProvider.updateAutomationComposition(automationComposition);
executor.execute(
() -> automationCompositionDeployPublisher.send(automationComposition, acDefinition.getServiceTemplate(),
startPhase, true));
@@ -112,8 +113,9 @@ public class SupervisionAcHandler {
}
automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
automationComposition.setCompositionTargetId(null);
- automationCompositionProvider.updateAutomationComposition(automationComposition);
var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate());
+ automationComposition.setPhase(startPhase);
+ automationCompositionProvider.updateAutomationComposition(automationComposition);
executor.execute(
() -> automationCompositionStateChangePublisher.send(automationComposition, startPhase, true));
}
@@ -136,8 +138,9 @@ public class SupervisionAcHandler {
AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.UNLOCKING);
}
automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
- automationCompositionProvider.updateAutomationComposition(automationComposition);
var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate());
+ automationComposition.setPhase(startPhase);
+ automationCompositionProvider.updateAutomationComposition(automationComposition);
executor.execute(
() -> automationCompositionStateChangePublisher.send(automationComposition, startPhase, true));
}
@@ -160,8 +163,9 @@ public class SupervisionAcHandler {
AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.LOCKING);
}
automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
- automationCompositionProvider.updateAutomationComposition(automationComposition);
var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate());
+ automationComposition.setPhase(startPhase);
+ automationCompositionProvider.updateAutomationComposition(automationComposition);
executor.execute(
() -> automationCompositionStateChangePublisher.send(automationComposition, startPhase, true));
}
@@ -187,8 +191,9 @@ public class SupervisionAcHandler {
public void delete(AutomationComposition automationComposition, AutomationCompositionDefinition acDefinition) {
AcmUtils.setCascadedState(automationComposition, DeployState.DELETING, LockState.NONE);
automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
- automationCompositionProvider.updateAutomationComposition(automationComposition);
var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate());
+ automationComposition.setPhase(startPhase);
+ automationCompositionProvider.updateAutomationComposition(automationComposition);
executor.execute(
() -> automationCompositionStateChangePublisher.send(automationComposition, startPhase, true));
}
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java
index 96e75df62..06d464671 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java
@@ -23,9 +23,7 @@
package org.onap.policy.clamp.acm.runtime.supervision;
import java.util.HashMap;
-import java.util.Map;
import java.util.UUID;
-import java.util.stream.Collectors;
import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionDeployPublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionStateChangePublisher;
@@ -51,9 +49,6 @@ import org.springframework.stereotype.Component;
public class SupervisionScanner {
private static final Logger LOGGER = LoggerFactory.getLogger(SupervisionScanner.class);
- private final TimeoutHandler<UUID> acTimeout = new TimeoutHandler<>();
- private final Map<UUID, Integer> phaseMap = new HashMap<>();
-
private final long maxStatusWaitMs;
private final AutomationCompositionProvider automationCompositionProvider;
@@ -79,8 +74,6 @@ public class SupervisionScanner {
this.acDefinitionProvider = acDefinitionProvider;
this.automationCompositionStateChangePublisher = automationCompositionStateChangePublisher;
this.automationCompositionDeployPublisher = automationCompositionDeployPublisher;
-
- acTimeout.setMaxWaitMs(acRuntimeParameterGroup.getParticipantParameters().getMaxStatusWaitMs());
this.maxStatusWaitMs = acRuntimeParameterGroup.getParticipantParameters().getMaxStatusWaitMs();
}
@@ -105,9 +98,6 @@ public class SupervisionScanner {
}
scanAutomationComposition(automationComposition, acDefinition.getServiceTemplate());
}
- var set = acList.stream().map(AutomationComposition::getInstanceId).collect(Collectors.toSet());
- acTimeout.removeIfNotPresent(set);
-
LOGGER.debug("Automation composition scan complete . . .");
}
@@ -143,17 +133,9 @@ public class SupervisionScanner {
LOGGER.debug("automation composition {} scanned, OK", automationComposition.getInstanceId());
// Clear Timeout on automation composition
- removeTimeout(automationComposition);
return;
}
- if (acTimeout.isTimeout(automationComposition.getInstanceId())
- && StateChangeResult.NO_ERROR.equals(automationComposition.getStateChangeResult())) {
- // retry by the user
- LOGGER.debug("clearing Timeout for the ac instance");
- clearTimeout(automationComposition, true);
- }
-
var completed = true;
var minSpNotCompleted = 1000; // min startPhase not completed
var maxSpNotCompleted = 0; // max startPhase not completed
@@ -173,18 +155,18 @@ public class SupervisionScanner {
}
if (completed) {
- LOGGER.debug("automation composition scan: transition state {} {} ", automationComposition.getDeployState(),
- automationComposition.getLockState());
+ LOGGER.debug("automation composition scan: transition state {} {} completed",
+ automationComposition.getDeployState(), automationComposition.getLockState());
complete(automationComposition);
} else {
- LOGGER.debug("automation composition scan: transition from state {} to {} not completed",
+ LOGGER.debug("automation composition scan: transition state {} {} not completed",
automationComposition.getDeployState(), automationComposition.getLockState());
if (DeployState.UPDATING.equals(automationComposition.getDeployState())
|| DeployState.MIGRATING.equals(automationComposition.getDeployState())) {
// UPDATING do not need phases
- handleTimeout(automationComposition);
+ handleTimeoutUpdate(automationComposition);
return;
}
@@ -192,14 +174,11 @@ public class SupervisionScanner {
AcmUtils.isForward(automationComposition.getDeployState(), automationComposition.getLockState());
var nextSpNotCompleted = isForward ? minSpNotCompleted : maxSpNotCompleted;
- var firstStartPhase = isForward ? defaultMin : defaultMax;
- if (nextSpNotCompleted != phaseMap.getOrDefault(automationComposition.getInstanceId(), firstStartPhase)) {
- phaseMap.put(automationComposition.getInstanceId(), nextSpNotCompleted);
- sendAutomationCompositionMsg(automationComposition, serviceTemplate, nextSpNotCompleted,
- firstStartPhase == nextSpNotCompleted);
+ if (nextSpNotCompleted != automationComposition.getPhase()) {
+ sendAutomationCompositionMsg(automationComposition, serviceTemplate, nextSpNotCompleted, false);
} else {
- handleTimeout(automationComposition);
+ handleTimeoutWithPhase(automationComposition, serviceTemplate);
}
}
}
@@ -213,6 +192,7 @@ public class SupervisionScanner {
}
automationComposition.setDeployState(AcmUtils.deployCompleted(deployState));
automationComposition.setLockState(AcmUtils.lockCompleted(deployState, automationComposition.getLockState()));
+ automationComposition.setPhase(null);
if (StateChangeResult.TIMEOUT.equals(automationComposition.getStateChangeResult())) {
automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
}
@@ -221,21 +201,6 @@ public class SupervisionScanner {
} else {
automationCompositionProvider.updateAutomationComposition(automationComposition);
}
-
- // Clear timeout on automation composition
- removeTimeout(automationComposition);
- }
-
- private void clearTimeout(AutomationComposition automationComposition, boolean cleanPhase) {
- acTimeout.clear(automationComposition.getInstanceId());
- if (cleanPhase) {
- phaseMap.remove(automationComposition.getInstanceId());
- }
- }
-
- private void removeTimeout(AutomationComposition automationComposition) {
- acTimeout.remove(automationComposition.getInstanceId());
- phaseMap.remove(automationComposition.getInstanceId());
}
private void handleTimeout(AutomationCompositionDefinition acDefinition) {
@@ -253,23 +218,60 @@ public class SupervisionScanner {
}
}
- private void handleTimeout(AutomationComposition automationComposition) {
- var instanceId = automationComposition.getInstanceId();
- if (acTimeout.isTimeout(instanceId)) {
+ private void handleTimeoutUpdate(AutomationComposition automationComposition) {
+ if (StateChangeResult.TIMEOUT.equals(automationComposition.getStateChangeResult())) {
LOGGER.debug("The ac instance is in timeout {}", automationComposition.getInstanceId());
return;
}
+ var now = TimestampHelper.nowEpochMilli();
+ var lastMsg = TimestampHelper.toEpochMilli(automationComposition.getLastMsg());
+ for (var element : automationComposition.getElements().values()) {
+ if (!AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState())) {
+ continue;
+ }
+ if ((now - lastMsg) > maxStatusWaitMs) {
+ LOGGER.debug("Report timeout for the ac instance {}", automationComposition.getInstanceId());
+ automationComposition.setStateChangeResult(StateChangeResult.TIMEOUT);
+ automationCompositionProvider.updateAutomationComposition(automationComposition);
+ break;
+ }
+ }
+ }
- if (acTimeout.getDuration(instanceId) > acTimeout.getMaxWaitMs()) {
- LOGGER.debug("Report timeout for the ac instance {}", automationComposition.getInstanceId());
- acTimeout.setTimeout(instanceId);
- automationComposition.setStateChangeResult(StateChangeResult.TIMEOUT);
- automationCompositionProvider.updateAutomationComposition(automationComposition);
+ private void handleTimeoutWithPhase(AutomationComposition automationComposition,
+ ToscaServiceTemplate serviceTemplate) {
+ if (StateChangeResult.TIMEOUT.equals(automationComposition.getStateChangeResult())) {
+ LOGGER.debug("The ac instance is in timeout {}", automationComposition.getInstanceId());
+ return;
+ }
+ int currentPhase = automationComposition.getPhase();
+ var now = TimestampHelper.nowEpochMilli();
+ var lastMsg = TimestampHelper.toEpochMilli(automationComposition.getLastMsg());
+ for (var element : automationComposition.getElements().values()) {
+ if (!AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState())) {
+ continue;
+ }
+ var toscaNodeTemplate = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates()
+ .get(element.getDefinition().getName());
+ int startPhase = ParticipantUtils.findStartPhase(toscaNodeTemplate.getProperties());
+ if (currentPhase != startPhase) {
+ continue;
+ }
+ if ((now - lastMsg) > maxStatusWaitMs) {
+ LOGGER.debug("Report timeout for the ac instance {}", automationComposition.getInstanceId());
+ automationComposition.setStateChangeResult(StateChangeResult.TIMEOUT);
+ automationCompositionProvider.updateAutomationComposition(automationComposition);
+ break;
+ }
}
}
private void sendAutomationCompositionMsg(AutomationComposition automationComposition,
ToscaServiceTemplate serviceTemplate, int startPhase, boolean firstStartPhase) {
+ automationComposition.setLastMsg(TimestampHelper.now());
+ automationComposition.setPhase(startPhase);
+ automationCompositionProvider.updateAutomationComposition(automationComposition);
+
if (DeployState.DEPLOYING.equals(automationComposition.getDeployState())) {
LOGGER.debug("retry message AutomationCompositionUpdate");
automationCompositionDeployPublisher.send(automationComposition, serviceTemplate, startPhase,
@@ -278,7 +280,5 @@ public class SupervisionScanner {
LOGGER.debug("retry message AutomationCompositionStateChange");
automationCompositionStateChangePublisher.send(automationComposition, startPhase, firstStartPhase);
}
- // Clear timeout on automation composition
- clearTimeout(automationComposition, false);
}
}
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/TimeoutHandler.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/TimeoutHandler.java
deleted file mode 100644
index 3b34252bf..000000000
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/TimeoutHandler.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * Copyright (C) 2023-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.
- * 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.acm.runtime.supervision;
-
-import java.time.Instant;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import lombok.Getter;
-import lombok.Setter;
-
-public class TimeoutHandler<K> {
- @Getter
- @Setter
- private long maxWaitMs;
-
- private final Set<K> mapTimeout = new HashSet<>();
- private final Map<K, Long> mapTimer = new HashMap<>();
-
- public long getDuration(K id) {
- mapTimer.putIfAbsent(id, getEpochMilli());
- return getEpochMilli() - mapTimer.get(id);
- }
-
- /**
- * Reset timer and timeout by id.
- *
- * @param id the id
- */
- public void clear(K id) {
- mapTimeout.remove(id);
- mapTimer.put(id, getEpochMilli());
- }
-
- /**
- * Remove timer and timeout by id.
- *
- * @param id the id
- */
- public void remove(K id) {
- mapTimeout.remove(id);
- mapTimer.remove(id);
- }
-
- /**
- * Remove elements that are not present in set.
- *
- * @param set the elements that should be present
- */
- public void removeIfNotPresent(final Set<K> set) {
- var res = mapTimeout.stream().filter(el -> !set.contains(el)).toList();
- if (!res.isEmpty()) {
- res.forEach(this::remove);
- }
- }
-
- public void setTimeout(K id) {
- mapTimeout.add(id);
- }
-
- public boolean isTimeout(K id) {
- return mapTimeout.contains(id);
- }
-
- protected long getEpochMilli() {
- return Instant.now().toEpochMilli();
- }
-}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java
index cd1a3856a..bcfdea1dd 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java
@@ -1,6 +1,6 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2023 Nordix Foundation.
+ * Copyright (C) 2021-2024 Nordix Foundation.
* Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -155,6 +155,7 @@ class InstantiationControllerTest extends CommonRestController {
var automationCompositionFromDb =
instantiationProvider.getAutomationComposition(compositionId, instResponse.getInstanceId());
+ automationCompositionFromRsc.setLastMsg(automationCompositionFromDb.getLastMsg());
assertNotNull(automationCompositionFromDb);
assertEquals(automationCompositionFromRsc, automationCompositionFromDb);
@@ -223,7 +224,9 @@ class InstantiationControllerTest extends CommonRestController {
var automationCompositionsQuery = rawresp.readEntity(AutomationCompositions.class);
assertNotNull(automationCompositionsQuery);
assertThat(automationCompositionsQuery.getAutomationCompositionList()).hasSize(1);
- assertEquals(automationComposition, automationCompositionsQuery.getAutomationCompositionList().get(0));
+ var automationCompositionRc = automationCompositionsQuery.getAutomationCompositionList().get(0);
+ automationComposition.setLastMsg(automationCompositionRc.getLastMsg());
+ assertEquals(automationComposition, automationCompositionRc);
}
@Test
@@ -241,6 +244,7 @@ class InstantiationControllerTest extends CommonRestController {
assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
var automationCompositionGet = rawresp.readEntity(AutomationComposition.class);
assertNotNull(automationCompositionGet);
+ automationComposition.setLastMsg(automationCompositionGet.getLastMsg());
assertEquals(automationComposition, automationCompositionGet);
}
@@ -272,7 +276,9 @@ class InstantiationControllerTest extends CommonRestController {
assertNotNull(automationCompositionsFromDb);
assertThat(automationCompositionsFromDb.getAutomationCompositionList()).hasSize(1);
- assertEquals(automationComposition, automationCompositionsFromDb.getAutomationCompositionList().get(0));
+ var acFromDb = automationCompositionsFromDb.getAutomationCompositionList().get(0);
+ automationComposition.setLastMsg(acFromDb.getLastMsg());
+ assertEquals(automationComposition, acFromDb);
}
@Test
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java
index 8ed250fba..d5163be14 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java
@@ -243,10 +243,15 @@ class SupervisionScannerTest {
var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
automationComposition.setDeployState(DeployState.DEPLOYING);
automationComposition.setLockState(LockState.NONE);
+ automationComposition.setPhase(0);
automationComposition.setCompositionId(compositionId);
- for (Map.Entry<UUID, AutomationCompositionElement> entry : automationComposition.getElements().entrySet()) {
+ for (var entry : automationComposition.getElements().entrySet()) {
entry.getValue().setDeployState(DeployState.DEPLOYING);
}
+ // the first element is already completed
+ automationComposition.getElements().entrySet().iterator().next().getValue()
+ .setDeployState(DeployState.DEPLOYED);
+
var automationCompositionProvider = mock(AutomationCompositionProvider.class);
when(automationCompositionProvider.getAcInstancesInTransition()).thenReturn(List.of(automationComposition));
@@ -261,14 +266,22 @@ class SupervisionScannerTest {
acRuntimeParameterGroup);
automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
+ automationComposition.setLastMsg(TimestampHelper.now());
scannerObj2.run();
verify(automationCompositionProvider, times(1)).updateAutomationComposition(any(AutomationComposition.class));
assertEquals(StateChangeResult.TIMEOUT, automationComposition.getStateChangeResult());
+ //already in TIMEOUT
+ clearInvocations(automationCompositionProvider);
+ scannerObj2.run();
+ verify(automationCompositionProvider, times(0)).updateAutomationComposition(any(AutomationComposition.class));
+
+ clearInvocations(automationCompositionProvider);
for (Map.Entry<UUID, AutomationCompositionElement> entry : automationComposition.getElements().entrySet()) {
entry.getValue().setDeployState(DeployState.DEPLOYED);
}
scannerObj2.run();
+ verify(automationCompositionProvider, times(1)).updateAutomationComposition(any(AutomationComposition.class));
assertEquals(StateChangeResult.NO_ERROR, automationComposition.getStateChangeResult());
}
@@ -277,6 +290,7 @@ class SupervisionScannerTest {
var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
automationComposition.setDeployState(DeployState.DEPLOYING);
automationComposition.setLockState(LockState.NONE);
+ automationComposition.setPhase(0);
automationComposition.setCompositionId(compositionId);
for (var element : automationComposition.getElements().values()) {
if ("org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement"
@@ -314,10 +328,15 @@ class SupervisionScannerTest {
var compositionTargetId = UUID.randomUUID();
automationComposition.setCompositionTargetId(compositionTargetId);
automationComposition.setLockState(LockState.LOCKED);
+ automationComposition.setLastMsg(TimestampHelper.now());
+ automationComposition.setPhase(0);
for (var element : automationComposition.getElements().values()) {
element.setDeployState(DeployState.DEPLOYED);
element.setLockState(LockState.LOCKED);
}
+ // first element is not migrated yet
+ automationComposition.getElements().entrySet().iterator().next().getValue()
+ .setDeployState(DeployState.MIGRATING);
var automationCompositionProvider = mock(AutomationCompositionProvider.class);
when(automationCompositionProvider.getAcInstancesInTransition()).thenReturn(List.of(automationComposition));
@@ -331,7 +350,15 @@ class SupervisionScannerTest {
acRuntimeParameterGroup);
supervisionScanner.run();
+ verify(automationCompositionProvider, times(0)).updateAutomationComposition(any(AutomationComposition.class));
+ assertEquals(DeployState.MIGRATING, automationComposition.getDeployState());
+
+ // first element is migrated
+ automationComposition.getElements().entrySet().iterator().next().getValue()
+ .setDeployState(DeployState.DEPLOYED);
+ supervisionScanner.run();
verify(automationCompositionProvider, times(1)).updateAutomationComposition(any(AutomationComposition.class));
+
assertEquals(DeployState.DEPLOYED, automationComposition.getDeployState());
assertEquals(compositionTargetId, automationComposition.getCompositionId());
}
@@ -342,6 +369,7 @@ class SupervisionScannerTest {
automationComposition.setDeployState(DeployState.DEPLOYED);
automationComposition.setLockState(LockState.UNLOCKING);
automationComposition.setCompositionId(compositionId);
+ automationComposition.setPhase(0);
for (var element : automationComposition.getElements().values()) {
if ("org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement"
.equals(element.getDefinition().getName())) {
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/TimeoutHandlerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/TimeoutHandlerTest.java
deleted file mode 100644
index 21c5b3d2c..000000000
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/TimeoutHandlerTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation.
- * ================================================================================
- * 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.acm.runtime.supervision;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.junit.jupiter.api.Test;
-
-class TimeoutHandlerTest {
-
- private static final int ID = 1;
-
- @Test
- void testFault() {
- var timeoutHandler = new TimeoutHandler<Integer>();
- timeoutHandler.setTimeout(ID);
- assertThat(timeoutHandler.isTimeout(ID)).isTrue();
- timeoutHandler.clear(ID);
- assertThat(timeoutHandler.isTimeout(ID)).isFalse();
- }
-
- @Test
- void testDuration() {
- var timeoutHandler = new TimeoutHandler<Integer>() {
- long epochMilli = 0;
-
- @Override
- protected long getEpochMilli() {
- return epochMilli;
- }
- };
- timeoutHandler.epochMilli = 100;
- var result = timeoutHandler.getDuration(ID);
- assertThat(result).isZero();
-
- timeoutHandler.epochMilli += 100;
- result = timeoutHandler.getDuration(ID);
- assertThat(result).isEqualTo(100);
-
- timeoutHandler.epochMilli += 100;
- result = timeoutHandler.getDuration(ID);
- assertThat(result).isEqualTo(200);
-
- timeoutHandler.epochMilli += 100;
- timeoutHandler.clear(ID);
- result = timeoutHandler.getDuration(ID);
- assertThat(result).isZero();
- }
-}