Merge "Add Synchronization topic in acm runtime"
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 0cf1f99..eb5b6dc 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 @@
@NonNull
private LockState lockState = LockState.NONE;
+ private String lastMsg;
+
+ private Integer phase;
+
private Map<UUID, AutomationCompositionElement> elements;
private StateChangeResult stateChangeResult;
@@ -69,6 +73,8 @@
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/concepts/Participant.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/Participant.java
index 5bdf4d3..6ddec61 100644
--- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/Participant.java
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/Participant.java
@@ -49,6 +49,9 @@
@NonNull
private Map<UUID, ParticipantSupportedElementType> participantSupportedElementTypes = new HashMap<>();
+ @NonNull
+ private Map<UUID, ParticipantReplica> replicas = new HashMap<>();
+
/**
* Copy constructor.
*
@@ -60,5 +63,6 @@
this.lastMsg = otherParticipant.lastMsg;
this.participantSupportedElementTypes = PfUtils.mapMap(otherParticipant.getParticipantSupportedElementTypes(),
ParticipantSupportedElementType::new);
+ this.replicas = PfUtils.mapMap(otherParticipant.replicas, ParticipantReplica::new);
}
}
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantReplica.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantReplica.java
new file mode 100644
index 0000000..23f7219
--- /dev/null
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantReplica.java
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * 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.
+ * 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.concepts;
+
+import java.util.UUID;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.NonNull;
+
+@NoArgsConstructor
+@Data
+@EqualsAndHashCode
+public class ParticipantReplica {
+
+ @NonNull
+ private UUID replicaId;
+
+ @NonNull
+ private ParticipantState participantState = ParticipantState.ON_LINE;
+
+ @NonNull
+ private String lastMsg;
+
+ /**
+ * Copy constructor.
+ *
+ * @param other the ParticipantReplica to copy from
+ */
+ public ParticipantReplica(ParticipantReplica other) {
+ this.replicaId = other.replicaId;
+ this.participantState = other.participantState;
+ this.lastMsg = other.lastMsg;
+ }
+}
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 5e27fde..0bf6a9e 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.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.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 @@
private StateChangeResult stateChangeResult;
@Column
+ @NotNull
+ private Timestamp lastMsg;
+
+ @Column
+ private Integer phase;
+
+ @Column
private String description;
@NotNull
@@ -149,6 +158,8 @@
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 @@
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 @@
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 @@
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/persistence/concepts/JpaParticipant.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipant.java
index cfde557..f35fff9 100644
--- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipant.java
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipant.java
@@ -41,6 +41,8 @@
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import org.apache.commons.lang3.ObjectUtils;
+import org.hibernate.annotations.LazyCollection;
+import org.hibernate.annotations.LazyCollectionOption;
import org.onap.policy.clamp.models.acm.concepts.Participant;
import org.onap.policy.clamp.models.acm.concepts.ParticipantState;
import org.onap.policy.clamp.models.acm.utils.TimestampHelper;
@@ -84,11 +86,18 @@
foreignKey = @ForeignKey(name = "supported_element_fk"))
private List<@NotNull @Valid JpaParticipantSupportedElementType> supportedElements;
+ @NotNull
+ @OneToMany
+ @LazyCollection(LazyCollectionOption.FALSE)
+ @JoinColumn(name = "participantId", referencedColumnName = "participantId",
+ foreignKey = @ForeignKey(name = "participant_replica_fk"))
+ private List<@NotNull @Valid JpaParticipantReplica> replicas;
+
/**
* The Default Constructor creates a {@link JpaParticipant} object with a null key.
*/
public JpaParticipant() {
- this(UUID.randomUUID().toString(), ParticipantState.ON_LINE, new ArrayList<>());
+ this(UUID.randomUUID().toString(), ParticipantState.ON_LINE, new ArrayList<>(), new ArrayList<>());
}
/**
@@ -96,13 +105,17 @@
*
* @param participantId the participant id
* @param participantState the state of the participant
+ * @param supportedElements the list of supported Element Type
+ * @param replicas the list of replica
*/
public JpaParticipant(@NonNull String participantId, @NonNull final ParticipantState participantState,
- @NonNull final List<JpaParticipantSupportedElementType> supportedElements) {
+ @NonNull final List<JpaParticipantSupportedElementType> supportedElements,
+ @NonNull final List<JpaParticipantReplica> replicas) {
this.participantId = participantId;
this.participantState = participantState;
this.supportedElements = supportedElements;
this.lastMsg = TimestampHelper.nowTimestamp();
+ this.replicas = replicas;
}
/**
@@ -115,6 +128,7 @@
this.description = copyConcept.description;
this.participantId = copyConcept.participantId;
this.supportedElements = copyConcept.supportedElements;
+ this.replicas = copyConcept.replicas;
this.lastMsg = copyConcept.lastMsg;
}
@@ -139,7 +153,9 @@
participant.getParticipantSupportedElementTypes()
.put(UUID.fromString(element.getId()), element.toAuthorative());
}
-
+ for (var replica : this.replicas) {
+ participant.getReplicas().put(UUID.fromString(replica.getReplicaId()), replica.toAuthorative());
+ }
return participant;
}
@@ -148,14 +164,22 @@
this.setParticipantState(participant.getParticipantState());
this.participantId = participant.getParticipantId().toString();
this.lastMsg = TimestampHelper.toTimestamp(participant.getLastMsg());
- this.supportedElements = new ArrayList<>(participant.getParticipantSupportedElementTypes().size());
+ this.supportedElements = new ArrayList<>(participant.getParticipantSupportedElementTypes().size());
for (var elementEntry : participant.getParticipantSupportedElementTypes().entrySet()) {
var jpaParticipantSupportedElementType = new JpaParticipantSupportedElementType();
jpaParticipantSupportedElementType.setParticipantId(this.participantId);
jpaParticipantSupportedElementType.fromAuthorative(elementEntry.getValue());
this.supportedElements.add(jpaParticipantSupportedElementType);
}
+
+ this.replicas = new ArrayList<>(participant.getReplicas().size());
+ for (var replicaEntry : participant.getReplicas().entrySet()) {
+ var jpaReplica = new JpaParticipantReplica();
+ jpaReplica.setParticipantId(this.participantId);
+ jpaReplica.fromAuthorative(replicaEntry.getValue());
+ this.replicas.add(jpaReplica);
+ }
}
@Override
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipantReplica.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipantReplica.java
new file mode 100644
index 0000000..beaab60
--- /dev/null
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipantReplica.java
@@ -0,0 +1,88 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * 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.
+ * 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.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.Inheritance;
+import jakarta.persistence.InheritanceType;
+import jakarta.persistence.Table;
+import java.sql.Timestamp;
+import java.util.UUID;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NonNull;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantReplica;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantState;
+import org.onap.policy.clamp.models.acm.utils.TimestampHelper;
+import org.onap.policy.common.parameters.annotations.NotNull;
+import org.onap.policy.models.base.PfAuthorative;
+import org.onap.policy.models.base.Validated;
+
+@Entity
+@Table(name = "ParticipantReplica")
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class JpaParticipantReplica extends Validated implements PfAuthorative<ParticipantReplica> {
+
+ @Id
+ @NotNull
+ private String replicaId;
+
+ @NotNull
+ @Column
+ private String participantId;
+
+ @Column
+ @NotNull
+ private ParticipantState participantState;
+
+ @Column
+ @NotNull
+ private Timestamp lastMsg;
+
+ public JpaParticipantReplica() {
+ this(UUID.randomUUID().toString(), UUID.randomUUID().toString());
+ }
+
+ public JpaParticipantReplica(@NonNull String replicaId, @NonNull String participantId) {
+ this.replicaId = replicaId;
+ this.participantId = participantId;
+ }
+
+ @Override
+ public ParticipantReplica toAuthorative() {
+ var participantReplica = new ParticipantReplica();
+ participantReplica.setReplicaId(UUID.fromString(replicaId));
+ participantReplica.setParticipantState(participantState);
+ participantReplica.setLastMsg(lastMsg.toString());
+ return participantReplica;
+ }
+
+ @Override
+ public void fromAuthorative(@NonNull ParticipantReplica participantReplica) {
+ this.replicaId = participantReplica.getReplicaId().toString();
+ this.participantState = participantReplica.getParticipantState();
+ this.lastMsg = TimestampHelper.toTimestamp(participantReplica.getLastMsg());
+ }
+}
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 0293bd3..5f523ad 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.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 @@
@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 @@
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/concepts/ParticipantReplicaTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantReplicaTest.java
new file mode 100644
index 0000000..8df6db6
--- /dev/null
+++ b/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantReplicaTest.java
@@ -0,0 +1,68 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * 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.
+ * 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.concepts;
+
+import static org.assertj.core.api.Assertions.assertThat;
+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 static org.junit.jupiter.api.Assertions.assertNotEquals;
+
+import java.util.UUID;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.clamp.models.acm.utils.CommonTestData;
+
+class ParticipantReplicaTest {
+
+ @Test
+ void testParticipantLombok() {
+ assertDoesNotThrow(() -> new ParticipantReplica());
+ var p0 = new ParticipantReplica();
+
+ assertThat(p0.toString()).contains("ParticipantReplica(");
+ assertThat(p0.hashCode()).isNotZero();
+ assertNotEquals(null, p0);
+
+ var p1 = new ParticipantReplica();
+
+ p1.setReplicaId(CommonTestData.getReplicaId());
+ p1.setParticipantState(ParticipantState.ON_LINE);
+
+ assertThat(p1.toString()).contains("ParticipantReplica(");
+ assertNotEquals(0, p1.hashCode());
+ assertNotEquals(p1, p0);
+ assertNotEquals(null, p1);
+
+ var p2 = new ParticipantReplica();
+ assertThatThrownBy(() -> p2.setParticipantState(null)).isInstanceOf(NullPointerException.class);
+ assertEquals(p2, p0);
+ }
+
+ @Test
+ void testCopyConstructor() {
+ var p0 = new ParticipantReplica();
+ p0.setReplicaId(UUID.randomUUID());
+ p0.setParticipantState(ParticipantState.ON_LINE);
+
+ var p2 = new ParticipantReplica(p0);
+ assertEquals(p2, p0);
+ }
+}
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 66554e7..b56e778 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.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.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 @@
@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 @@
@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 @@
@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 @@
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 @@
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/concepts/JpaParticipantReplicaTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipantReplicaTest.java
new file mode 100644
index 0000000..d777608
--- /dev/null
+++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipantReplicaTest.java
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * 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.
+ * 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 static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+
+import java.util.UUID;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantReplica;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantState;
+import org.onap.policy.clamp.models.acm.utils.TimestampHelper;
+
+class JpaParticipantReplicaTest {
+
+ @Test
+ void testJpaParticipantReplicaConstructor() {
+ assertThatThrownBy(() -> new JpaParticipantReplica(UUID.randomUUID().toString(), null))
+ .hasMessageMatching("participantId is marked .*ull but is null");
+
+ assertThatThrownBy(() -> new JpaParticipantReplica(null, UUID.randomUUID().toString()))
+ .hasMessageMatching("replicaId is marked .*ull but is null");
+
+ assertDoesNotThrow(() -> new JpaParticipantReplica());
+ assertDoesNotThrow(() -> new JpaParticipantReplica(UUID.randomUUID().toString(), UUID.randomUUID().toString()));
+ }
+
+ @Test
+ void testJpaParticipantReplica() {
+ var p0 = new JpaParticipantReplica();
+
+ assertThat(p0.toString()).contains("JpaParticipantReplica(");
+ assertThat(p0.hashCode()).isNotZero();
+ assertNotEquals(null, p0);
+
+ var p1 = new JpaParticipantReplica();
+ p1.setParticipantState(ParticipantState.ON_LINE);
+
+ assertThat(p1.toString()).contains("ParticipantReplica(");
+ assertNotEquals(0, p1.hashCode());
+ assertNotEquals(p1, p0);
+ assertNotEquals(null, p1);
+
+ var p2 = new JpaParticipantReplica();
+ p2.setReplicaId(p0.getReplicaId());
+ p2.setParticipantId(p0.getParticipantId());
+ p2.setLastMsg(p0.getLastMsg());
+ p2.setParticipantState(p0.getParticipantState());
+ assertEquals(p2, p0);
+ }
+}
diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipantTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipantTest.java
index e64a689..e0f2f55 100644
--- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipantTest.java
+++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaParticipantTest.java
@@ -52,20 +52,25 @@
assertThatThrownBy(() -> new JpaParticipant((JpaParticipant) null))
.hasMessageMatching("copyConcept is marked .*ull but is null");
- assertThatThrownBy(() -> new JpaParticipant(null, null, null)).hasMessageMatching(NULL_KEY_ERROR);
-
- assertThatThrownBy(() -> new JpaParticipant(null, ParticipantState.ON_LINE, new ArrayList<>()))
+ assertThatThrownBy(() -> new JpaParticipant(null, ParticipantState.ON_LINE,
+ new ArrayList<>(), new ArrayList<>()))
.hasMessageMatching(NULL_KEY_ERROR);
- assertThatThrownBy(() -> new JpaParticipant(UUID.randomUUID().toString(), null, new ArrayList<>()))
+ assertThatThrownBy(() -> new JpaParticipant(UUID.randomUUID().toString(), null,
+ new ArrayList<>(), new ArrayList<>()))
.hasMessageMatching("participantState is marked .*ull but is null");
- assertThatThrownBy(() -> new JpaParticipant(UUID.randomUUID().toString(), ParticipantState.ON_LINE, null))
+ assertThatThrownBy(() -> new JpaParticipant(UUID.randomUUID().toString(), ParticipantState.ON_LINE,
+ null, new ArrayList<>()))
.hasMessageMatching("supportedElements is marked .*ull but is null");
+ assertThatThrownBy(() -> new JpaParticipant(UUID.randomUUID().toString(), ParticipantState.ON_LINE,
+ new ArrayList<>(), null))
+ .hasMessageMatching("replicas is marked .*ull but is null");
+
assertDoesNotThrow(() -> new JpaParticipant());
assertDoesNotThrow(() -> new JpaParticipant(UUID.randomUUID().toString(),
- ParticipantState.ON_LINE, new ArrayList<>()));
+ ParticipantState.ON_LINE, new ArrayList<>(), new ArrayList<>()));
}
@Test
@@ -158,6 +163,7 @@
testParticipant.setParticipantId(UUID.randomUUID());
testParticipant.setLastMsg(TimestampHelper.now());
testParticipant.setParticipantSupportedElementTypes(new LinkedHashMap<>());
+ testParticipant.setReplicas(new LinkedHashMap<>());
return testParticipant;
}
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 463e958..8e7e50d 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 @@
var createdAutomationComposition = automationCompositionProvider.createAutomationComposition(inputAc);
inputAc.setInstanceId(createdAutomationComposition.getInstanceId());
+ inputAc.setLastMsg(createdAutomationComposition.getLastMsg());
assertEquals(inputAc, createdAutomationComposition);
}
diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/CommonTestData.java b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/CommonTestData.java
index b8075c3..3bd1549 100644
--- a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/CommonTestData.java
+++ b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/CommonTestData.java
@@ -51,9 +51,9 @@
}
/**
- * Returns participantId for test cases.
+ * Returns participant replica Id for test cases.
*
- * @return participant Id
+ * @return replica Id
*/
public static UUID getReplicaId() {
return REPLICA_ID;
diff --git a/models/src/test/resources/providers/TestAutomationCompositions.json b/models/src/test/resources/providers/TestAutomationCompositions.json
index 24f5a48..c75337b 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/models/src/test/resources/providers/TestParticipant.json b/models/src/test/resources/providers/TestParticipant.json
index 3f19baa..3335865 100644
--- a/models/src/test/resources/providers/TestParticipant.json
+++ b/models/src/test/resources/providers/TestParticipant.json
@@ -22,5 +22,12 @@
"typeName": "org.onap.policy.clamp.acm.AutomationCompositionElement",
"typeVersion": "1.0.0"
}
+ },
+ "replicas": {
+ "82fd8ef9-1d1e-4343-9b28-7f9564ee3de6":{
+ "replicaId": "82fd8ef9-1d1e-4343-9b28-7f9564ee3de6",
+ "lastMsg": "2024-05-22 10:04:37.6020187",
+ "participantState": "ON_LINE"
+ }
}
}
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 d6fa5d8..802c660 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 @@
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 @@
}
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 @@
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 @@
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 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 96e75df..06d4646 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 @@
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 @@
this.acDefinitionProvider = acDefinitionProvider;
this.automationCompositionStateChangePublisher = automationCompositionStateChangePublisher;
this.automationCompositionDeployPublisher = automationCompositionDeployPublisher;
-
- acTimeout.setMaxWaitMs(acRuntimeParameterGroup.getParticipantParameters().getMaxStatusWaitMs());
this.maxStatusWaitMs = acRuntimeParameterGroup.getParticipantParameters().getMaxStatusWaitMs();
}
@@ -105,9 +98,6 @@
}
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 @@
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 @@
}
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 @@
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 @@
}
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 @@
} 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 @@
}
}
- 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 @@
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 3b34252..0000000
--- 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 cd1a385..bcfdea1 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 @@
var automationCompositionFromDb =
instantiationProvider.getAutomationComposition(compositionId, instResponse.getInstanceId());
+ automationCompositionFromRsc.setLastMsg(automationCompositionFromDb.getLastMsg());
assertNotNull(automationCompositionFromDb);
assertEquals(automationCompositionFromRsc, automationCompositionFromDb);
@@ -223,7 +224,9 @@
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 @@
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 @@
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 8ed250f..d5163be 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 21c5b3d..0000000
--- 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();
- }
-}