aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java50
-rw-r--r--models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java18
-rw-r--r--models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionDefinitionRepository.java11
-rw-r--r--models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java13
-rw-r--r--models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java81
-rw-r--r--models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProviderTest.java26
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java12
-rw-r--r--participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java14
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java2
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java15
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java3
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java69
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/TimeoutHandler.java18
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java48
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java115
15 files changed, 383 insertions, 112 deletions
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java
index a9b9a0cfd..9eb5e7a32 100644
--- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.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.
@@ -28,10 +28,14 @@ import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
+import org.onap.policy.clamp.models.acm.concepts.NodeTemplateState;
+import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
import org.onap.policy.clamp.models.acm.document.base.ToscaServiceTemplateValidation;
import org.onap.policy.clamp.models.acm.document.concepts.DocToscaServiceTemplate;
import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionDefinition;
+import org.onap.policy.clamp.models.acm.persistence.concepts.JpaNodeTemplateState;
import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionDefinitionRepository;
+import org.onap.policy.clamp.models.acm.persistence.repository.NodeTemplateStateRepository;
import org.onap.policy.clamp.models.acm.utils.AcmUtils;
import org.onap.policy.common.parameters.BeanValidationResult;
import org.onap.policy.models.base.PfModelRuntimeException;
@@ -47,6 +51,7 @@ import org.springframework.transaction.annotation.Transactional;
public class AcDefinitionProvider {
private final AutomationCompositionDefinitionRepository acmDefinitionRepository;
+ private final NodeTemplateStateRepository nodeTemplateStateRepository;
/**
* Create Automation Composition Definition.
@@ -125,6 +130,43 @@ public class AcDefinitionProvider {
}
/**
+ * Update Ac Definition AcTypeState, StateChangeResult and restarting.
+ *
+ * @param compositionId The UUID of the automation composition definition to update
+ * @param state the AcTypeState
+ * @param stateChangeResult the StateChangeResult
+ * @param restarting restarting process
+ */
+ public void updateAcDefinitionState(UUID compositionId, AcTypeState state, StateChangeResult stateChangeResult,
+ Boolean restarting) {
+ var jpaUpdate = acmDefinitionRepository.findById(compositionId.toString());
+ if (jpaUpdate.isEmpty()) {
+ String errorMessage = "update of Automation Composition Definition \"" + compositionId
+ + "\" failed, Automation Composition Definition does not exist";
+ throw new PfModelRuntimeException(Response.Status.NOT_FOUND, errorMessage);
+ }
+ var acDefinition = jpaUpdate.get();
+ acDefinition.setState(state);
+ acDefinition.setStateChangeResult(stateChangeResult);
+ acDefinition.setRestarting(restarting);
+ acmDefinitionRepository.save(acDefinition);
+ acmDefinitionRepository.flush();
+ }
+
+ /**
+ * Update Ac DefinitionElement.
+ *
+ * @param nodeTemplateState the NodeTemplateState
+ * @param compositionId The UUID of the automation composition definition
+ */
+ public void updateAcDefinitionElement(NodeTemplateState nodeTemplateState, UUID compositionId) {
+ var jpaNodeTemplateState = new JpaNodeTemplateState(
+ nodeTemplateState.getNodeTemplateStateId().toString(), compositionId.toString());
+ jpaNodeTemplateState.fromAuthorative(nodeTemplateState);
+ nodeTemplateStateRepository.save(jpaNodeTemplateState);
+ }
+
+ /**
* Delete Automation Composition Definition.
*
* @param compositionId The UUID of the automation composition definition to delete
@@ -173,13 +215,13 @@ public class AcDefinitionProvider {
}
/**
- * Get Automation Composition Definitions.
+ * Get Automation Composition Definitions in transition.
*
* @return the Automation Composition Definitions found
*/
@Transactional(readOnly = true)
- public List<AutomationCompositionDefinition> getAllAcDefinitions() {
- var jpaList = acmDefinitionRepository.findAll();
+ public List<AutomationCompositionDefinition> getAllAcDefinitionsInTransition() {
+ var jpaList = acmDefinitionRepository.findByStateIn(List.of(AcTypeState.PRIMING, AcTypeState.DEPRIMING));
return ProviderUtils.asEntityList(jpaList);
}
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java
index 1ffcc1b6e..8be12960b 100644
--- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.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.
* ================================================================================
@@ -127,7 +127,7 @@ public class AutomationCompositionProvider {
@NonNull final AutomationComposition automationComposition) {
var result = automationCompositionRepository.save(ProviderUtils.getJpaAndValidate(automationComposition,
JpaAutomationComposition::new, "automation composition"));
-
+ automationCompositionRepository.flush();
// Return the saved automation composition
return result.toAuthorative();
}
@@ -145,6 +145,20 @@ public class AutomationCompositionProvider {
}
/**
+ * Get all automation compositions in transition..
+ *
+ * @return all automation compositions found
+ */
+ @Transactional(readOnly = true)
+ public List<AutomationComposition> getAcInstancesInTransition() {
+ var jpaList = automationCompositionRepository.findByDeployStateIn(List.of(DeployState.DEPLOYING,
+ DeployState.UNDEPLOYING, DeployState.DELETING, DeployState.UPDATING, DeployState.MIGRATING));
+ jpaList.addAll(automationCompositionRepository.findByLockStateIn(
+ List.of(LockState.LOCKING, LockState.UNLOCKING)));
+ return ProviderUtils.asEntityList(jpaList);
+ }
+
+ /**
* Get automation compositions.
*
* @param name the name of the automation composition to get, null to get all automation compositions
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionDefinitionRepository.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionDefinitionRepository.java
index df4d7dffa..86de60bf2 100644
--- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionDefinitionRepository.java
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionDefinitionRepository.java
@@ -1,6 +1,6 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2022 Nordix Foundation.
+ * Copyright (C) 2022,2024 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,13 +20,16 @@
package org.onap.policy.clamp.models.acm.persistence.repository;
+import java.util.Collection;
+import java.util.List;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionDefinition;
import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.repository.query.QueryByExampleExecutor;
import org.springframework.stereotype.Repository;
@Repository
public interface AutomationCompositionDefinitionRepository
- extends JpaRepository<JpaAutomationCompositionDefinition, String>,
- QueryByExampleExecutor<JpaAutomationCompositionDefinition> {
+ extends JpaRepository<JpaAutomationCompositionDefinition, String> {
+
+ List<JpaAutomationCompositionDefinition> findByStateIn(Collection<AcTypeState> states);
}
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java
index bb8b3e6d9..d61dfb41b 100644
--- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java
@@ -1,6 +1,6 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2022 Nordix Foundation.
+ * Copyright (C) 2021-2022,2024 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,15 +20,20 @@
package org.onap.policy.clamp.models.acm.persistence.repository;
+import java.util.Collection;
import java.util.List;
+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.persistence.concepts.JpaAutomationComposition;
import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.repository.query.QueryByExampleExecutor;
import org.springframework.stereotype.Repository;
@Repository
-public interface AutomationCompositionRepository
- extends JpaRepository<JpaAutomationComposition, String>, QueryByExampleExecutor<JpaAutomationComposition> {
+public interface AutomationCompositionRepository extends JpaRepository<JpaAutomationComposition, String> {
List<JpaAutomationComposition> findByCompositionId(String compositionId);
+
+ List<JpaAutomationComposition> findByDeployStateIn(Collection<DeployState> deployStates);
+
+ List<JpaAutomationComposition> findByLockStateIn(Collection<LockState> lockStates);
}
diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java
index 78095c907..1e067c8f6 100644
--- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java
+++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.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.
@@ -38,9 +38,12 @@ import org.mockito.Mockito;
import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
import org.onap.policy.clamp.models.acm.concepts.NodeTemplateState;
+import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
import org.onap.policy.clamp.models.acm.document.concepts.DocToscaServiceTemplate;
import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionDefinition;
+import org.onap.policy.clamp.models.acm.persistence.concepts.JpaNodeTemplateState;
import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionDefinitionRepository;
+import org.onap.policy.clamp.models.acm.persistence.repository.NodeTemplateStateRepository;
import org.onap.policy.clamp.models.acm.utils.CommonTestData;
import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
@@ -91,7 +94,7 @@ class AcDefinitionProviderTest {
when(acmDefinitionRepository.save(any(JpaAutomationCompositionDefinition.class)))
.thenReturn(new JpaAutomationCompositionDefinition(acmDefinition));
- var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository);
+ var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository, null);
var result = acDefinitionProvider
.createAutomationCompositionDefinition(inputServiceTemplate, ELEMENT_NAME, NODE_TYPE);
@@ -101,11 +104,9 @@ class AcDefinitionProviderTest {
@Test
void testToscaWithInvalidElement() {
- var docServiceTemplate = new DocToscaServiceTemplate(inputServiceTemplate);
- var acmDefinition = getAcDefinition(docServiceTemplate);
var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class);
- var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository);
+ var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository, null);
assertThatThrownBy(() -> acDefinitionProvider
.createAutomationCompositionDefinition(inputServiceTemplate, INVALID_ELEMENT_NAME, NODE_TYPE))
@@ -114,11 +115,9 @@ class AcDefinitionProviderTest {
@Test
void testToscaWithInvalidNodeType() {
- var docServiceTemplate = new DocToscaServiceTemplate(inputServiceTemplate);
- var acmDefinition = getAcDefinition(docServiceTemplate);
var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class);
- var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository);
+ var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository, null);
assertThatThrownBy(() -> acDefinitionProvider
.createAutomationCompositionDefinition(inputServiceTemplate, ELEMENT_NAME, INVALID_NODE_TYPE))
@@ -135,7 +134,7 @@ class AcDefinitionProviderTest {
when(acmDefinitionRepository.save(any(JpaAutomationCompositionDefinition.class)))
.thenReturn(new JpaAutomationCompositionDefinition(acmDefinition));
- var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository);
+ var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository, null);
inputServiceTemplate.setMetadata(new HashMap<>());
var result = acDefinitionProvider
.createAutomationCompositionDefinition(inputServiceTemplate, ELEMENT_NAME, NODE_TYPE);
@@ -147,7 +146,7 @@ class AcDefinitionProviderTest {
@Test
void testUpdateServiceTemplate() {
var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class);
- var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository);
+ var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository, null);
acDefinitionProvider.updateServiceTemplate(UUID.randomUUID(), inputServiceTemplate, ELEMENT_NAME, NODE_TYPE);
verify(acmDefinitionRepository).save(any(JpaAutomationCompositionDefinition.class));
}
@@ -155,19 +154,45 @@ class AcDefinitionProviderTest {
@Test
void testUpdateAcDefinition() {
var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class);
- var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository);
+ var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository, null);
var acmDefinition = getAcDefinition(new DocToscaServiceTemplate(inputServiceTemplate));
acDefinitionProvider.updateAcDefinition(acmDefinition, NODE_TYPE);
verify(acmDefinitionRepository).save(any(JpaAutomationCompositionDefinition.class));
}
@Test
+ void testUpdateAcDefinitionState() {
+ var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class);
+ var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository, null);
+ var acmDefinition = getAcDefinition(new DocToscaServiceTemplate(inputServiceTemplate));
+ acmDefinition.setState(AcTypeState.PRIMING);
+ var jpa = new JpaAutomationCompositionDefinition(acmDefinition);
+ when(acmDefinitionRepository.findById(acmDefinition.getCompositionId().toString()))
+ .thenReturn(Optional.of(jpa));
+ acDefinitionProvider.updateAcDefinitionState(acmDefinition.getCompositionId(), AcTypeState.PRIMED,
+ StateChangeResult.NO_ERROR, false);
+ verify(acmDefinitionRepository).save(jpa);
+ }
+
+ @Test
+ void testUpdateAcDefinitionElement() {
+ var nodeTemplateState = new NodeTemplateState();
+ nodeTemplateState.setNodeTemplateId(new ToscaConceptIdentifier("name", "1.0.0"));
+ nodeTemplateState.setNodeTemplateStateId(UUID.randomUUID());
+ nodeTemplateState.setState(AcTypeState.PRIMED);
+ var nodeTemplateStateRepository = mock(NodeTemplateStateRepository.class);
+ var acDefinitionProvider = new AcDefinitionProvider(null, nodeTemplateStateRepository);
+ acDefinitionProvider.updateAcDefinitionElement(nodeTemplateState, UUID.randomUUID());
+ verify(nodeTemplateStateRepository).save(any(JpaNodeTemplateState.class));
+ }
+
+ @Test
void testGetAcDefinition() {
var jpa = new JpaAutomationCompositionDefinition();
jpa.fromAuthorative(getAcDefinition(new DocToscaServiceTemplate(inputServiceTemplate)));
var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class);
when(acmDefinitionRepository.findById(jpa.getCompositionId())).thenReturn(Optional.of(jpa));
- var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository);
+ var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository, null);
var result = acDefinitionProvider.getAcDefinition(UUID.fromString(jpa.getCompositionId()));
assertThat(result).isNotNull();
}
@@ -175,7 +200,7 @@ class AcDefinitionProviderTest {
@Test
void testGetAcDefinitionNotFound() {
var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class);
- var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository);
+ var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository, null);
var compositionId = UUID.randomUUID();
assertThatThrownBy(() -> acDefinitionProvider.getAcDefinition(compositionId))
.hasMessage("Get serviceTemplate \"" + compositionId + "\" failed, serviceTemplate does not exist");
@@ -187,20 +212,24 @@ class AcDefinitionProviderTest {
jpa.fromAuthorative(getAcDefinition(new DocToscaServiceTemplate(inputServiceTemplate)));
var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class);
when(acmDefinitionRepository.findById(jpa.getCompositionId())).thenReturn(Optional.of(jpa));
- var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository);
- var result = acDefinitionProvider.findAcDefinition(UUID.fromString(jpa.getCompositionId()));
- assertThat(result).isNotNull();
+ var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository, null);
+ var compositionId = UUID.fromString(jpa.getCompositionId());
+ var result = acDefinitionProvider.findAcDefinition(compositionId);
+ assertThat(result).isNotEmpty();
}
@Test
- void testGetAllAcDefinitions() {
+ void getAllAcDefinitionsInTransition() {
+ var acDefinition = getAcDefinition(new DocToscaServiceTemplate(inputServiceTemplate));
+ acDefinition.setState(AcTypeState.PRIMING);
var jpa = new JpaAutomationCompositionDefinition();
- jpa.fromAuthorative(getAcDefinition(new DocToscaServiceTemplate(inputServiceTemplate)));
+ jpa.fromAuthorative(acDefinition);
var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class);
- when(acmDefinitionRepository.findAll()).thenReturn(List.of(jpa));
- var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository);
- var result = acDefinitionProvider.getAllAcDefinitions();
- assertThat(result).hasSize(1);
+ when(acmDefinitionRepository.findByStateIn(List.of(AcTypeState.PRIMING, AcTypeState.DEPRIMING)))
+ .thenReturn(List.of(jpa));
+ var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository, null);
+ var result = acDefinitionProvider.getAllAcDefinitionsInTransition();
+ assertThat(result).isNotEmpty();
}
@Test
@@ -212,7 +241,7 @@ class AcDefinitionProviderTest {
when(acmDefinitionRepository.findById(acmDefinition.getCompositionId().toString()))
.thenReturn(Optional.of(new JpaAutomationCompositionDefinition(acmDefinition)));
- var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository);
+ var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository, null);
var result = acDefinitionProvider.deleteAcDefintion(acmDefinition.getCompositionId());
assertThat(result).isEqualTo(docServiceTemplate.toAuthorative());
@@ -222,7 +251,7 @@ class AcDefinitionProviderTest {
void testDeleteServiceTemplateEmpty() {
var compositionId = UUID.randomUUID();
var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class);
- var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository);
+ var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository, null);
assertThatThrownBy(() -> acDefinitionProvider.deleteAcDefintion(compositionId))
.hasMessage("delete of Automation Composition Definition \"" + compositionId
+ "\" failed, Automation Composition Definition does not exist");
@@ -236,7 +265,7 @@ class AcDefinitionProviderTest {
when(acmDefinitionRepository.findAll(Mockito.<Example<JpaAutomationCompositionDefinition>>any()))
.thenReturn(List.of(new JpaAutomationCompositionDefinition(acmDefinition)));
- var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository);
+ var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository, null);
var result = acDefinitionProvider.getServiceTemplateList(inputServiceTemplate.getName(),
inputServiceTemplate.getVersion());
@@ -252,7 +281,7 @@ class AcDefinitionProviderTest {
when(acmDefinitionRepository.findAll(Mockito.<Example<JpaAutomationCompositionDefinition>>any()))
.thenReturn(List.of(new JpaAutomationCompositionDefinition(acmDefinition)));
- var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository);
+ var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository, null);
var result = acDefinitionProvider.getServiceTemplateList(null,
inputServiceTemplate.getVersion());
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 b09ddda74..463e958f3 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
@@ -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.
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@@ -40,6 +41,8 @@ import org.mockito.Mockito;
import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementInfo;
import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionInfo;
import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions;
+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.persistence.concepts.JpaAutomationComposition;
import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionElement;
import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionElementRepository;
@@ -177,6 +180,27 @@ class AutomationCompositionProviderTest {
}
@Test
+ void testGetAcInstancesInTransition() {
+ inputAutomationCompositions.getAutomationCompositionList().get(0).setDeployState(DeployState.DEPLOYING);
+ inputAutomationCompositions.getAutomationCompositionList().get(1).setLockState(LockState.LOCKING);
+ inputAutomationCompositionsJpa.get(0).setDeployState(DeployState.DEPLOYING);
+ inputAutomationCompositionsJpa.get(1).setLockState(LockState.LOCKING);
+
+ List<JpaAutomationComposition> res1 = new ArrayList<>();
+ res1.add(inputAutomationCompositionsJpa.get(0));
+ var automationCompositionRepository = mock(AutomationCompositionRepository.class);
+ var automationCompositionProvider = new AutomationCompositionProvider(automationCompositionRepository,
+ mock(AutomationCompositionElementRepository.class));
+ when(automationCompositionRepository.findByDeployStateIn(List.of(DeployState.DEPLOYING,
+ DeployState.UNDEPLOYING, DeployState.DELETING, DeployState.UPDATING, DeployState.MIGRATING)))
+ .thenReturn(res1);
+ when(automationCompositionRepository.findByLockStateIn(List.of(LockState.LOCKING, LockState.UNLOCKING)))
+ .thenReturn(List.of(inputAutomationCompositionsJpa.get(1)));
+ var acList = automationCompositionProvider.getAcInstancesInTransition();
+ assertEquals(inputAutomationCompositions.getAutomationCompositionList(), acList);
+ }
+
+ @Test
void testDeleteAutomationComposition() {
var automationCompositionRepository = mock(AutomationCompositionRepository.class);
var automationCompositionProvider = new AutomationCompositionProvider(automationCompositionRepository,
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java
index fd82c37ba..fefa637da 100644
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java
@@ -40,6 +40,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.ParticipantDeploy;
import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantState;
import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils;
import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionDeploy;
@@ -47,6 +48,7 @@ import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCom
import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionStateChange;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantMessageType;
+import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantPrimeAck;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.PropertiesUpdate;
import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder;
@@ -428,6 +430,16 @@ public class AutomationCompositionHandler {
var acElementsDefinitions = cacheProvider.getAcElementsDefinitions().get(compositionId);
if (acElementsDefinitions == null) {
// this participant does not handle this composition
+ var participantPrimeAck = new ParticipantPrimeAck();
+ participantPrimeAck.setCompositionId(compositionId);
+ participantPrimeAck.setMessage("Already deprimed or never primed");
+ participantPrimeAck.setResult(true);
+ participantPrimeAck.setResponseTo(messageId);
+ participantPrimeAck.setCompositionState(AcTypeState.COMMISSIONED);
+ participantPrimeAck.setStateChangeResult(StateChangeResult.NO_ERROR);
+ participantPrimeAck.setParticipantId(cacheProvider.getParticipantId());
+ participantPrimeAck.setState(ParticipantState.ON_LINE);
+ publisher.sendParticipantPrimeAck(participantPrimeAck);
return;
}
var list = new ArrayList<>(acElementsDefinitions.values());
diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java
index 661c009f6..b8fd3b42d 100644
--- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java
+++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java
@@ -47,6 +47,7 @@ import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCom
import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionDeployAck;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionStateChange;
+import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantPrimeAck;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.PropertiesUpdate;
import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder;
@@ -273,7 +274,7 @@ class AutomationCompositionHandlerTest {
}
@Test
- void handleComposiotDeprimeTest() {
+ void handleCompositionDeprimeTest() {
var acElementDefinition = new AutomationCompositionElementDefinition();
acElementDefinition.setAcElementDefinitionId(new ToscaConceptIdentifier("key", "1.0.0"));
var toscaNodeTemplate = new ToscaNodeTemplate();
@@ -292,6 +293,17 @@ class AutomationCompositionHandlerTest {
}
@Test
+ void handleCompositionAlreadyDeprimedTest() {
+ var messageId = UUID.randomUUID();
+ var compositionId = UUID.randomUUID();
+ var participantMessagePublisher = mock(ParticipantMessagePublisher.class);
+ var ach = new AutomationCompositionHandler(mock(CacheProvider.class), participantMessagePublisher,
+ mock(ThreadHandler.class));
+ ach.deprime(messageId, compositionId);
+ verify(participantMessagePublisher).sendParticipantPrimeAck(any(ParticipantPrimeAck.class));
+ }
+
+ @Test
void restartedTest() {
var acElementDefinition = new AutomationCompositionElementDefinition();
acElementDefinition.setAcElementDefinitionId(new ToscaConceptIdentifier("key", "1.0.0"));
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 a5dc0e78e..d6fa5d8d7 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
@@ -204,7 +204,6 @@ public class SupervisionAcHandler {
description = "AUTOMATION_COMPOSITION_DEPLOY_ACK messages received")
public void handleAutomationCompositionUpdateAckMessage(
AutomationCompositionDeployAck automationCompositionAckMessage) {
- LOGGER.debug("AutomationComposition Update Ack message received {}", automationCompositionAckMessage);
setAcElementStateInDb(automationCompositionAckMessage);
}
@@ -219,7 +218,6 @@ public class SupervisionAcHandler {
description = "AUTOMATION_COMPOSITION_STATECHANGE_ACK messages received")
public void handleAutomationCompositionStateChangeAckMessage(
AutomationCompositionDeployAck automationCompositionAckMessage) {
- LOGGER.debug("AutomationComposition StateChange Ack message received {}", automationCompositionAckMessage);
setAcElementStateInDb(automationCompositionAckMessage);
}
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java
index 660cb28a5..963e4830e 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java
@@ -52,7 +52,6 @@ public class SupervisionHandler {
*/
@Timed(value = "listener.participant_prime_ack", description = "PARTICIPANT_PRIME_ACK messages received")
public void handleParticipantMessage(ParticipantPrimeAck participantPrimeAckMessage) {
- LOGGER.debug("Participant Prime Ack message received {}", participantPrimeAckMessage);
var acDefinitionOpt = acDefinitionProvider.findAcDefinition(participantPrimeAckMessage.getCompositionId());
if (acDefinitionOpt.isEmpty()) {
LOGGER.warn("AC Definition not found in database {}", participantPrimeAckMessage.getCompositionId());
@@ -74,8 +73,10 @@ public class SupervisionHandler {
|| AcTypeState.PRIMED.equals(acDefinition.getState()) ? AcTypeState.PRIMED : AcTypeState.COMMISSIONED;
var msgInErrors = StateChangeResult.FAILED.equals(participantPrimeAckMessage.getStateChangeResult());
boolean inProgress = !StateChangeResult.FAILED.equals(acDefinition.getStateChangeResult());
+ boolean toUpdate = false;
if (inProgress && msgInErrors) {
acDefinition.setStateChangeResult(StateChangeResult.FAILED);
+ toUpdate = true;
}
boolean completed = true;
@@ -85,6 +86,7 @@ public class SupervisionHandler {
element.setMessage(participantPrimeAckMessage.getMessage());
element.setState(participantPrimeAckMessage.getCompositionState());
element.setRestarting(null);
+ acDefinitionProvider.updateAcDefinitionElement(element, acDefinition.getCompositionId());
}
if (!finalState.equals(element.getState())) {
completed = false;
@@ -95,16 +97,19 @@ public class SupervisionHandler {
}
if (inProgress && !msgInErrors && completed) {
+ toUpdate = true;
acDefinition.setState(finalState);
if (StateChangeResult.TIMEOUT.equals(acDefinition.getStateChangeResult())) {
acDefinition.setStateChangeResult(StateChangeResult.NO_ERROR);
}
}
- if (!restarting) {
+ if (!restarting && acDefinition.getRestarting() != null) {
+ toUpdate = true;
acDefinition.setRestarting(null);
}
- acDefinitionProvider.updateAcDefinition(acDefinition,
- acRuntimeParameterGroup.getAcmParameters().getToscaCompositionName());
+ if (toUpdate) {
+ acDefinitionProvider.updateAcDefinitionState(acDefinition.getCompositionId(), acDefinition.getState(),
+ acDefinition.getStateChangeResult(), acDefinition.getRestarting());
+ }
}
-
}
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java
index 7a2c58d50..24c256fa4 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java
@@ -74,7 +74,6 @@ public class SupervisionParticipantHandler {
@MessageIntercept
@Timed(value = "listener.participant_register", description = "PARTICIPANT_REGISTER messages received")
public void handleParticipantMessage(ParticipantRegister participantRegisterMsg) {
- LOGGER.debug("Participant Register received {}", participantRegisterMsg);
var participantOpt = participantProvider.findParticipant(participantRegisterMsg.getParticipantId());
if (participantOpt.isPresent()) {
@@ -100,7 +99,6 @@ public class SupervisionParticipantHandler {
@MessageIntercept
@Timed(value = "listener.participant_deregister", description = "PARTICIPANT_DEREGISTER messages received")
public void handleParticipantMessage(ParticipantDeregister participantDeregisterMsg) {
- LOGGER.debug("Participant Deregister received {}", participantDeregisterMsg);
var participantOpt = participantProvider.findParticipant(participantDeregisterMsg.getParticipantId());
if (participantOpt.isPresent()) {
@@ -120,7 +118,6 @@ public class SupervisionParticipantHandler {
@MessageIntercept
@Timed(value = "listener.participant_status", description = "PARTICIPANT_STATUS messages received")
public void handleParticipantMessage(ParticipantStatus participantStatusMsg) {
- LOGGER.debug("Participant Status received {}", participantStatusMsg);
var participantOpt = participantProvider.findParticipant(participantStatusMsg.getParticipantId());
if (participantOpt.isEmpty()) {
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 33118fab7..881969a90 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
@@ -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.
* ================================================================================
@@ -23,8 +23,11 @@
package org.onap.policy.clamp.acm.runtime.supervision;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
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;
@@ -56,7 +59,6 @@ public class SupervisionScanner {
private final AcDefinitionProvider acDefinitionProvider;
private final AutomationCompositionStateChangePublisher automationCompositionStateChangePublisher;
private final AutomationCompositionDeployPublisher automationCompositionDeployPublisher;
- private final AcRuntimeParameterGroup acRuntimeParameterGroup;
/**
* Constructor for instantiating SupervisionScanner.
@@ -76,7 +78,6 @@ public class SupervisionScanner {
this.acDefinitionProvider = acDefinitionProvider;
this.automationCompositionStateChangePublisher = automationCompositionStateChangePublisher;
this.automationCompositionDeployPublisher = automationCompositionDeployPublisher;
- this.acRuntimeParameterGroup = acRuntimeParameterGroup;
acTimeout.setMaxWaitMs(acRuntimeParameterGroup.getParticipantParameters().getMaxStatusWaitMs());
}
@@ -87,20 +88,27 @@ public class SupervisionScanner {
public void run() {
LOGGER.debug("Scanning automation compositions in the database . . .");
- var list = acDefinitionProvider.getAllAcDefinitions();
- for (var acDefinition : list) {
- if (AcTypeState.PRIMING.equals(acDefinition.getState())
- || AcTypeState.DEPRIMING.equals(acDefinition.getState())) {
- scanAutomationCompositionDefinition(acDefinition);
- } else {
- acTimeout.clear(acDefinition.getCompositionId());
- var acList =
- automationCompositionProvider.getAcInstancesByCompositionId(acDefinition.getCompositionId());
- for (var automationComposition : acList) {
- scanAutomationComposition(automationComposition, acDefinition.getServiceTemplate());
- }
+ var acDefinitionList = acDefinitionProvider.getAllAcDefinitionsInTransition();
+ for (var acDefinition : acDefinitionList) {
+ scanAutomationCompositionDefinition(acDefinition);
+ }
+ Set<UUID> set = new HashSet<>();
+ set.addAll(acDefinitionList
+ .stream().map(AutomationCompositionDefinition::getCompositionId).collect(Collectors.toSet()));
+
+ var acList = automationCompositionProvider.getAcInstancesInTransition();
+ HashMap<UUID, AutomationCompositionDefinition> acDefinitionMap = new HashMap<>();
+ for (var automationComposition : acList) {
+ var acDefinition = acDefinitionMap.get(automationComposition.getCompositionId());
+ if (acDefinition == null) {
+ acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId());
+ acDefinitionMap.put(acDefinition.getCompositionId(), acDefinition);
}
+ scanAutomationComposition(automationComposition, acDefinition.getServiceTemplate());
}
+ set.addAll(
+ acList.stream().map(AutomationComposition::getInstanceId).collect(Collectors.toSet()));
+ acTimeout.removeIfNotPresent(set);
LOGGER.debug("Automation composition scan complete . . .");
}
@@ -110,7 +118,7 @@ public class SupervisionScanner {
LOGGER.debug("automation definition {} scanned, OK", acDefinition.getCompositionId());
// Clear Timeout on ac Definition
- acTimeout.clear(acDefinition.getCompositionId());
+ acTimeout.remove(acDefinition.getCompositionId());
return;
}
@@ -121,7 +129,21 @@ public class SupervisionScanner {
acTimeout.clear(acDefinition.getCompositionId());
}
- handleTimeout(acDefinition);
+ boolean completed = true;
+ var finalState = AcTypeState.PRIMING.equals(acDefinition.getState())
+ || AcTypeState.PRIMED.equals(acDefinition.getState()) ? AcTypeState.PRIMED : AcTypeState.COMMISSIONED;
+ for (var element : acDefinition.getElementStateMap().values()) {
+ if (!finalState.equals(element.getState())) {
+ completed = false;
+ }
+ }
+ if (completed) {
+ acDefinitionProvider.updateAcDefinitionState(acDefinition.getCompositionId(), finalState,
+ StateChangeResult.NO_ERROR, null);
+ acTimeout.remove(acDefinition.getCompositionId());
+ } else {
+ handleTimeout(acDefinition);
+ }
}
private void scanAutomationComposition(final AutomationComposition automationComposition,
@@ -134,7 +156,7 @@ public class SupervisionScanner {
LOGGER.debug("automation composition {} scanned, OK", automationComposition.getInstanceId());
// Clear Timeout on automation composition
- clearTimeout(automationComposition, true);
+ removeTimeout(automationComposition);
return;
}
@@ -214,7 +236,7 @@ public class SupervisionScanner {
}
// Clear timeout on automation composition
- clearTimeout(automationComposition, true);
+ removeTimeout(automationComposition);
}
private void clearTimeout(AutomationComposition automationComposition, boolean cleanPhase) {
@@ -224,6 +246,11 @@ public class SupervisionScanner {
}
}
+ private void removeTimeout(AutomationComposition automationComposition) {
+ acTimeout.remove(automationComposition.getInstanceId());
+ phaseMap.remove(automationComposition.getInstanceId());
+ }
+
private void handleTimeout(AutomationCompositionDefinition acDefinition) {
var compositionId = acDefinition.getCompositionId();
if (acTimeout.isTimeout(compositionId)) {
@@ -235,8 +262,8 @@ public class SupervisionScanner {
LOGGER.debug("Report timeout for the ac definition {}", acDefinition.getCompositionId());
acTimeout.setTimeout(compositionId);
acDefinition.setStateChangeResult(StateChangeResult.TIMEOUT);
- acDefinitionProvider.updateAcDefinition(acDefinition,
- acRuntimeParameterGroup.getAcmParameters().getToscaCompositionName());
+ acDefinitionProvider.updateAcDefinitionState(acDefinition.getCompositionId(),
+ acDefinition.getState(), acDefinition.getStateChangeResult(), acDefinition.getRestarting());
}
}
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
index 976c91438..3b34252bf 100644
--- 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
@@ -1,6 +1,6 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation.
+ * 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.
@@ -33,8 +33,8 @@ public class TimeoutHandler<K> {
@Setter
private long maxWaitMs;
- private Set<K> mapTimeout = new HashSet<>();
- private Map<K, Long> mapTimer = new HashMap<>();
+ private final Set<K> mapTimeout = new HashSet<>();
+ private final Map<K, Long> mapTimer = new HashMap<>();
public long getDuration(K id) {
mapTimer.putIfAbsent(id, getEpochMilli());
@@ -61,6 +61,18 @@ public class TimeoutHandler<K> {
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);
}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java
index 4028f57f6..448666f8f 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java
@@ -22,6 +22,7 @@ package org.onap.policy.clamp.acm.runtime.supervision;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.onap.policy.clamp.acm.runtime.util.CommonTestData.TOSCA_SERVICE_TEMPLATE_YAML;
@@ -77,13 +78,16 @@ class SupervisionHandlerTest {
void testParticipantPrimeAck() {
var participantPrimeAckMessage = new ParticipantPrimeAck();
participantPrimeAckMessage.setParticipantId(CommonTestData.getParticipantId());
+ participantPrimeAckMessage.setCompositionState(AcTypeState.PRIMED);
participantPrimeAckMessage.setState(ParticipantState.ON_LINE);
var acDefinition = CommonTestData.createAcDefinition(
InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML), AcTypeState.PRIMING);
+ acDefinition.setStateChangeResult(StateChangeResult.NO_ERROR);
participantPrimeAckMessage.setCompositionId(acDefinition.getCompositionId());
- acDefinition.getElementStateMap().values().iterator().next()
- .setParticipantId(CommonTestData.getParticipantId());
+ for (var element : acDefinition.getElementStateMap().values()) {
+ element.setParticipantId(CommonTestData.getParticipantId());
+ }
var acDefinitionProvider = mock(AcDefinitionProvider.class);
when(acDefinitionProvider.findAcDefinition(acDefinition.getCompositionId()))
@@ -93,7 +97,10 @@ class SupervisionHandlerTest {
handler.handleParticipantMessage(participantPrimeAckMessage);
verify(acDefinitionProvider).findAcDefinition(any());
- verify(acDefinitionProvider).updateAcDefinition(any(), any());
+ verify(acDefinitionProvider, times(acDefinition.getElementStateMap().size()))
+ .updateAcDefinitionElement(any(), any());
+ verify(acDefinitionProvider).updateAcDefinitionState(acDefinition.getCompositionId(), AcTypeState.PRIMED,
+ StateChangeResult.NO_ERROR, null);
}
@Test
@@ -117,6 +124,39 @@ class SupervisionHandlerTest {
handler.handleParticipantMessage(participantPrimeAckMessage);
verify(acDefinitionProvider).findAcDefinition(any());
- verify(acDefinitionProvider).updateAcDefinition(any(), any());
+ verify(acDefinitionProvider).updateAcDefinitionElement(any(), any());
+ verify(acDefinitionProvider).updateAcDefinitionState(acDefinition.getCompositionId(), AcTypeState.PRIMING,
+ StateChangeResult.FAILED, null);
+ }
+
+ @Test
+ void testParticipantPrimeAckRestarted() {
+ var participantPrimeAckMessage = new ParticipantPrimeAck();
+ participantPrimeAckMessage.setParticipantId(CommonTestData.getParticipantId());
+ participantPrimeAckMessage.setCompositionState(AcTypeState.PRIMED);
+ participantPrimeAckMessage.setState(ParticipantState.ON_LINE);
+
+ var acDefinition = CommonTestData.createAcDefinition(
+ InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML), AcTypeState.PRIMED);
+ acDefinition.setStateChangeResult(StateChangeResult.TIMEOUT);
+ acDefinition.setRestarting(true);
+ participantPrimeAckMessage.setCompositionId(acDefinition.getCompositionId());
+ for (var element : acDefinition.getElementStateMap().values()) {
+ element.setParticipantId(CommonTestData.getParticipantId());
+ element.setRestarting(true);
+ }
+
+ var acDefinitionProvider = mock(AcDefinitionProvider.class);
+ when(acDefinitionProvider.findAcDefinition(acDefinition.getCompositionId()))
+ .thenReturn(Optional.of(acDefinition));
+
+ var handler = new SupervisionHandler(acDefinitionProvider, CommonTestData.getTestParamaterGroup());
+
+ handler.handleParticipantMessage(participantPrimeAckMessage);
+ verify(acDefinitionProvider).findAcDefinition(any());
+ verify(acDefinitionProvider, times(acDefinition.getElementStateMap().size()))
+ .updateAcDefinitionElement(any(), any());
+ verify(acDefinitionProvider).updateAcDefinitionState(acDefinition.getCompositionId(), AcTypeState.PRIMED,
+ StateChangeResult.NO_ERROR, null);
}
}
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 a1fad46b1..7d0b4252a 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
@@ -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.
@@ -25,6 +25,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -46,6 +47,7 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition
import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
import org.onap.policy.clamp.models.acm.concepts.DeployState;
import org.onap.policy.clamp.models.acm.concepts.LockState;
+import org.onap.policy.clamp.models.acm.concepts.NodeTemplateState;
import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
@@ -57,82 +59,131 @@ class SupervisionScannerTest {
private static final UUID compositionId = UUID.randomUUID();
- private AcDefinitionProvider createAcDefinitionProvider(AcTypeState acTypeState,
- StateChangeResult stateChangeResult) {
+ private AutomationCompositionDefinition createAutomationCompositionDefinition(AcTypeState acTypeState,
+ StateChangeResult stateChangeResult) {
var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
var acDefinition = new AutomationCompositionDefinition();
acDefinition.setState(acTypeState);
acDefinition.setStateChangeResult(stateChangeResult);
acDefinition.setCompositionId(compositionId);
acDefinition.setServiceTemplate(serviceTemplate);
+ var node = new NodeTemplateState();
+ node.setState(AcTypeState.PRIMING);
+ node.setNodeTemplateStateId(UUID.randomUUID());
+ acDefinition.setElementStateMap(Map.of(node.getNodeTemplateStateId().toString(), node));
+ return acDefinition;
+ }
+
+ private AcDefinitionProvider createAcDefinitionProvider(AutomationCompositionDefinition acDefinition) {
var acDefinitionProvider = mock(AcDefinitionProvider.class);
- when(acDefinitionProvider.getAllAcDefinitions()).thenReturn(List.of(Objects.requireNonNull(acDefinition)));
+ var acTypeState = acDefinition.getState();
+ if (AcTypeState.PRIMING.equals(acTypeState) || AcTypeState.DEPRIMING.equals(acTypeState)) {
+ when(acDefinitionProvider.getAllAcDefinitionsInTransition())
+ .thenReturn(List.of(Objects.requireNonNull(acDefinition)));
+ }
+ when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acDefinition);
return acDefinitionProvider;
}
+ private AcDefinitionProvider createAcDefinitionProvider(AcTypeState acTypeState,
+ StateChangeResult stateChangeResult) {
+ return createAcDefinitionProvider(createAutomationCompositionDefinition(acTypeState, stateChangeResult));
+ }
+
private AcDefinitionProvider createAcDefinitionProvider() {
return createAcDefinitionProvider(AcTypeState.PRIMED, StateChangeResult.NO_ERROR);
}
@Test
- void testScannerOrderedFailed() {
+ void testAcDefinitionPrimeFailed() {
var acDefinitionProvider = createAcDefinitionProvider(AcTypeState.PRIMING, StateChangeResult.FAILED);
var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
var supervisionScanner = new SupervisionScanner(mock(AutomationCompositionProvider.class), acDefinitionProvider,
mock(AutomationCompositionStateChangePublisher.class), mock(AutomationCompositionDeployPublisher.class),
acRuntimeParameterGroup);
supervisionScanner.run();
- verify(acDefinitionProvider, times(0)).updateAcDefinition(any(AutomationCompositionDefinition.class),
- eq(CommonTestData.TOSCA_COMP_NAME));
+ verify(acDefinitionProvider, times(0)).updateAcDefinitionState(any(), any(), any(), any());
}
@Test
- void testScannerOrderedPriming() {
- var acDefinitionProvider = createAcDefinitionProvider(AcTypeState.PRIMING, StateChangeResult.NO_ERROR);
+ void testAcDefinitionPrimeTimeout() {
+ var acDefinition = createAutomationCompositionDefinition(AcTypeState.PRIMING, StateChangeResult.NO_ERROR);
+ var acDefinitionProvider = createAcDefinitionProvider(acDefinition);
var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
var supervisionScanner = new SupervisionScanner(mock(AutomationCompositionProvider.class), acDefinitionProvider,
mock(AutomationCompositionStateChangePublisher.class), mock(AutomationCompositionDeployPublisher.class),
acRuntimeParameterGroup);
supervisionScanner.run();
- verify(acDefinitionProvider, times(0)).updateAcDefinition(any(AutomationCompositionDefinition.class),
- eq(CommonTestData.TOSCA_COMP_NAME));
+ // Ac Definition in Priming state
+ verify(acDefinitionProvider, times(0)).updateAcDefinitionState(any(), any(), any(), any());
acRuntimeParameterGroup.getParticipantParameters().setMaxStatusWaitMs(-1);
supervisionScanner = new SupervisionScanner(mock(AutomationCompositionProvider.class), acDefinitionProvider,
mock(AutomationCompositionStateChangePublisher.class), mock(AutomationCompositionDeployPublisher.class),
acRuntimeParameterGroup);
supervisionScanner.run();
- verify(acDefinitionProvider).updateAcDefinition(any(AutomationCompositionDefinition.class),
- eq(CommonTestData.TOSCA_COMP_NAME));
+ // set Timeout
+ verify(acDefinitionProvider).updateAcDefinitionState(acDefinition.getCompositionId(), acDefinition.getState(),
+ StateChangeResult.TIMEOUT, null);
+
+ clearInvocations(acDefinitionProvider);
+ acDefinition.setStateChangeResult(StateChangeResult.TIMEOUT);
+ supervisionScanner.run();
+ // already in Timeout
+ verify(acDefinitionProvider, times(0)).updateAcDefinitionState(any(), any(), any(), any());
+
+ clearInvocations(acDefinitionProvider);
+ // retry by the user
+ acDefinition.setStateChangeResult(StateChangeResult.NO_ERROR);
+ supervisionScanner.run();
+ // set Timeout
+ verify(acDefinitionProvider).updateAcDefinitionState(acDefinition.getCompositionId(), acDefinition.getState(),
+ StateChangeResult.TIMEOUT, null);
+
+ clearInvocations(acDefinitionProvider);
+ for (var element : acDefinition.getElementStateMap().values()) {
+ element.setState(AcTypeState.PRIMED);
+ }
+ supervisionScanner.run();
+ // completed
+ verify(acDefinitionProvider).updateAcDefinitionState(acDefinition.getCompositionId(), AcTypeState.PRIMED,
+ StateChangeResult.NO_ERROR, null);
}
@Test
- void testScannerOrderedStateEqualsToState() {
+ void testAcNotInTransitionOrFailed() {
var automationCompositionProvider = mock(AutomationCompositionProvider.class);
var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
var automationCompositionDeployPublisher = mock(AutomationCompositionDeployPublisher.class);
var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
- when(automationCompositionProvider.getAcInstancesByCompositionId(compositionId))
- .thenReturn(List.of(automationComposition));
+ automationComposition.setCompositionId(compositionId);
+ when(automationCompositionProvider.getAcInstancesInTransition()).thenReturn(List.of(automationComposition));
var supervisionScanner = new SupervisionScanner(automationCompositionProvider, createAcDefinitionProvider(),
automationCompositionStateChangePublisher, automationCompositionDeployPublisher,
acRuntimeParameterGroup);
+
+ // not in transition
supervisionScanner.run();
+ verify(automationCompositionProvider, times(0)).updateAutomationComposition(any(AutomationComposition.class));
+ automationComposition.setDeployState(DeployState.DEPLOYING);
+ automationComposition.setStateChangeResult(StateChangeResult.FAILED);
+ supervisionScanner.run();
+ // failed
verify(automationCompositionProvider, times(0)).updateAutomationComposition(any(AutomationComposition.class));
}
@Test
- void testScannerOrderedStateDifferentToState() {
+ void testAcUndeployCompleted() {
var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
automationComposition.setDeployState(DeployState.UNDEPLOYING);
automationComposition.setLockState(LockState.NONE);
+ automationComposition.setCompositionId(compositionId);
var automationCompositionProvider = mock(AutomationCompositionProvider.class);
- when(automationCompositionProvider.getAcInstancesByCompositionId(compositionId))
- .thenReturn(List.of(automationComposition));
+ when(automationCompositionProvider.getAcInstancesInTransition()).thenReturn(List.of(automationComposition));
var automationCompositionDeployPublisher = mock(AutomationCompositionDeployPublisher.class);
var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
@@ -147,13 +198,13 @@ class SupervisionScannerTest {
}
@Test
- void testScannerDelete() {
+ void testAcDeleted() {
var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
automationComposition.setDeployState(DeployState.DELETING);
automationComposition.setLockState(LockState.NONE);
+ automationComposition.setCompositionId(compositionId);
var automationCompositionProvider = mock(AutomationCompositionProvider.class);
- when(automationCompositionProvider.getAcInstancesByCompositionId(compositionId))
- .thenReturn(List.of(automationComposition));
+ when(automationCompositionProvider.getAcInstancesInTransition()).thenReturn(List.of(automationComposition));
var automationCompositionDeployPublisher = mock(AutomationCompositionDeployPublisher.class);
var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
@@ -171,8 +222,8 @@ class SupervisionScannerTest {
void testScanner() {
var automationCompositionProvider = mock(AutomationCompositionProvider.class);
var automationComposition = new AutomationComposition();
- when(automationCompositionProvider.getAcInstancesByCompositionId(compositionId))
- .thenReturn(List.of(automationComposition));
+ automationComposition.setCompositionId(compositionId);
+ when(automationCompositionProvider.getAcInstancesInTransition()).thenReturn(List.of(automationComposition));
var automationCompositionDeployPublisher = mock(AutomationCompositionDeployPublisher.class);
var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
@@ -191,12 +242,12 @@ class SupervisionScannerTest {
var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
automationComposition.setDeployState(DeployState.DEPLOYING);
automationComposition.setLockState(LockState.NONE);
+ automationComposition.setCompositionId(compositionId);
for (Map.Entry<UUID, AutomationCompositionElement> entry : automationComposition.getElements().entrySet()) {
entry.getValue().setDeployState(DeployState.DEPLOYING);
}
var automationCompositionProvider = mock(AutomationCompositionProvider.class);
- when(automationCompositionProvider.getAcInstancesByCompositionId(compositionId))
- .thenReturn(List.of(automationComposition));
+ when(automationCompositionProvider.getAcInstancesInTransition()).thenReturn(List.of(automationComposition));
var automationCompositionDeployPublisher = mock(AutomationCompositionDeployPublisher.class);
var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
@@ -225,6 +276,7 @@ class SupervisionScannerTest {
var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
automationComposition.setDeployState(DeployState.DEPLOYING);
automationComposition.setLockState(LockState.NONE);
+ automationComposition.setCompositionId(compositionId);
for (var element : automationComposition.getElements().values()) {
if ("org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement"
.equals(element.getDefinition().getName())) {
@@ -237,8 +289,7 @@ class SupervisionScannerTest {
}
var automationCompositionProvider = mock(AutomationCompositionProvider.class);
- when(automationCompositionProvider.getAcInstancesByCompositionId(compositionId))
- .thenReturn(List.of(automationComposition));
+ when(automationCompositionProvider.getAcInstancesInTransition()).thenReturn(List.of(automationComposition));
var automationCompositionDeployPublisher = mock(AutomationCompositionDeployPublisher.class);
var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
@@ -258,6 +309,7 @@ class SupervisionScannerTest {
void testSendAutomationCompositionMigrate() {
var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
automationComposition.setDeployState(DeployState.MIGRATING);
+ automationComposition.setCompositionId(compositionId);
var compositionTargetId = UUID.randomUUID();
automationComposition.setCompositionTargetId(compositionTargetId);
automationComposition.setLockState(LockState.LOCKED);
@@ -267,8 +319,7 @@ class SupervisionScannerTest {
}
var automationCompositionProvider = mock(AutomationCompositionProvider.class);
- when(automationCompositionProvider.getAcInstancesByCompositionId(compositionId))
- .thenReturn(List.of(automationComposition));
+ when(automationCompositionProvider.getAcInstancesInTransition()).thenReturn(List.of(automationComposition));
var automationCompositionDeployPublisher = mock(AutomationCompositionDeployPublisher.class);
var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
@@ -289,6 +340,7 @@ class SupervisionScannerTest {
var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
automationComposition.setDeployState(DeployState.DEPLOYED);
automationComposition.setLockState(LockState.UNLOCKING);
+ automationComposition.setCompositionId(compositionId);
for (var element : automationComposition.getElements().values()) {
if ("org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement"
.equals(element.getDefinition().getName())) {
@@ -301,8 +353,7 @@ class SupervisionScannerTest {
}
var automationCompositionProvider = mock(AutomationCompositionProvider.class);
- when(automationCompositionProvider.getAcInstancesByCompositionId(compositionId))
- .thenReturn(List.of(automationComposition));
+ when(automationCompositionProvider.getAcInstancesInTransition()).thenReturn(List.of(automationComposition));
var automationCompositionDeployPublisher = mock(AutomationCompositionDeployPublisher.class);
var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);