aboutsummaryrefslogtreecommitdiffstats
path: root/runtime-acm
diff options
context:
space:
mode:
authorrameshiyer27 <ramesh.murugan.iyer@est.tech>2023-05-18 16:47:10 +0100
committerLiam Fallon <liam.fallon@est.tech>2023-05-23 15:25:03 +0000
commit461bbdb67733552e78037bd96ca7efdfd3015e25 (patch)
treeefab4e35ea578f058879922588cd711d0e22d0ce /runtime-acm
parent4539ab951ef81839d38641fa09f2cbd490d71a63 (diff)
Update AC Element properties on the DEPLOYED state
User can update the instance property values on DEPLOYED state. The runtime sends PROPERTY_UPDATE event to the participants and the updated values are stored on the runtime database. Participants can implement the update method to perform the required action. Issue-ID: POLICY-4682 Signed-off-by: zrrmmua <ramesh.murugan.iyer@est.tech> Change-Id: Ic35fba669b5ffcf2c75d6deaa8c309d58e4026f0
Diffstat (limited to 'runtime-acm')
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java65
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java12
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcElementPropertiesPublisher.java89
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java16
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java13
5 files changed, 163 insertions, 32 deletions
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java
index 4665fec37..787547860 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java
@@ -21,6 +21,8 @@
package org.onap.policy.clamp.acm.runtime.instantiation;
+
+import java.util.Map;
import java.util.UUID;
import javax.validation.Valid;
import javax.ws.rs.core.Response;
@@ -29,8 +31,10 @@ import lombok.AllArgsConstructor;
import org.onap.policy.clamp.acm.runtime.supervision.SupervisionAcHandler;
import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
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.messages.rest.instantiation.AcInstanceStateUpdate;
import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse;
import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
@@ -100,33 +104,72 @@ public class AutomationCompositionInstantiationProvider {
*/
public InstantiationResponse updateAutomationComposition(UUID compositionId,
AutomationComposition automationComposition) {
+ var response = new InstantiationResponse();
var instanceId = automationComposition.getInstanceId();
var acToUpdate = automationCompositionProvider.getAutomationComposition(instanceId);
if (!compositionId.equals(acToUpdate.getCompositionId())) {
throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
}
- if (!DeployState.UNDEPLOYED.equals(acToUpdate.getDeployState())) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
- "Not allow to update for state in " + acToUpdate.getDeployState());
+ if (DeployState.UNDEPLOYED.equals(acToUpdate.getDeployState())) {
+ acToUpdate.setElements(automationComposition.getElements());
+ acToUpdate.setName(automationComposition.getName());
+ acToUpdate.setVersion(automationComposition.getVersion());
+ acToUpdate.setDescription(automationComposition.getDescription());
+ acToUpdate.setDerivedFrom(automationComposition.getDerivedFrom());
+ var validationResult = validateAutomationComposition(acToUpdate);
+ if (!validationResult.isValid()) {
+ throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
+ }
+ automationComposition = automationCompositionProvider.updateAutomationComposition(acToUpdate);
+ response.setInstanceId(instanceId);
+ response.setAffectedAutomationComposition(automationComposition.getKey().asIdentifier());
+ return response;
+
+ } else if (DeployState.DEPLOYED.equals(acToUpdate.getDeployState())
+ && LockState.LOCKED.equals(acToUpdate.getLockState())) {
+ return updateDeployedAutomationComposition(compositionId, automationComposition, acToUpdate);
+ }
+ throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
+ "Not allowed to update in the state " + acToUpdate.getDeployState());
+ }
+
+ /**
+ * Update deployed AC Element properties.
+ *
+ * @param compositionId The UUID of the automation composition definition
+ * @param automationComposition the automation composition
+ * @param acToBeUpdated the composition to be updated
+ * @return the result of the update
+ */
+ public InstantiationResponse updateDeployedAutomationComposition(UUID compositionId,
+ AutomationComposition automationComposition,
+ AutomationComposition acToBeUpdated) {
+
+ // Iterate and update the element property values
+ for (Map.Entry<UUID, AutomationCompositionElement> dbAcElement : acToBeUpdated.getElements().entrySet()) {
+ var elementId = dbAcElement.getKey();
+ if (automationComposition.getElements().containsKey(elementId)) {
+ dbAcElement.getValue().getProperties().putAll(automationComposition.getElements().get(elementId)
+ .getProperties());
+ }
}
- acToUpdate.setElements(automationComposition.getElements());
- acToUpdate.setName(automationComposition.getName());
- acToUpdate.setVersion(automationComposition.getVersion());
- acToUpdate.setDescription(automationComposition.getDescription());
- acToUpdate.setDerivedFrom(automationComposition.getDerivedFrom());
- var validationResult = validateAutomationComposition(acToUpdate);
+ // Publish property update event to the participants
+ supervisionAcHandler.update(acToBeUpdated);
+
+ var validationResult = validateAutomationComposition(acToBeUpdated);
if (!validationResult.isValid()) {
throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
}
- automationComposition = automationCompositionProvider.updateAutomationComposition(acToUpdate);
-
+ automationComposition = automationCompositionProvider.updateAutomationComposition(acToBeUpdated);
var response = new InstantiationResponse();
+ var instanceId = automationComposition.getInstanceId();
response.setInstanceId(instanceId);
response.setAffectedAutomationComposition(automationComposition.getKey().asIdentifier());
return response;
}
+
/**
* Validate AutomationComposition.
*
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 654c31194..da3cbc399 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
@@ -25,6 +25,7 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
import lombok.AllArgsConstructor;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.AcElementPropertiesPublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionDeployPublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionStateChangePublisher;
import org.onap.policy.clamp.models.acm.concepts.AcElementDeployAck;
@@ -55,6 +56,8 @@ public class SupervisionAcHandler {
private final AutomationCompositionDeployPublisher automationCompositionDeployPublisher;
private final AutomationCompositionStateChangePublisher automationCompositionStateChangePublisher;
+ private final AcElementPropertiesPublisher acElementPropertiesPublisher;
+
/**
* Handle Deploy an AutomationComposition instance.
*
@@ -109,6 +112,15 @@ public class SupervisionAcHandler {
}
/**
+ * Handle Element property update on a deployed instance.
+ * @param automationComposition the AutomationComposition
+ */
+ public void update(AutomationComposition automationComposition) {
+ AcmUtils.setCascadedState(automationComposition, DeployState.UPDATING, LockState.NONE);
+ acElementPropertiesPublisher.send(automationComposition);
+ }
+
+ /**
* Handle Delete an AutomationComposition instance.
*
* @param automationComposition the AutomationComposition
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcElementPropertiesPublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcElementPropertiesPublisher.java
new file mode 100644
index 000000000..c5f33ad97
--- /dev/null
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcElementPropertiesPublisher.java
@@ -0,0 +1,89 @@
+/*-
+ * ============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.comm;
+
+import io.micrometer.core.annotation.Timed;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.function.UnaryOperator;
+import lombok.AllArgsConstructor;
+import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
+import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.PropertiesUpdate;
+import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
+import org.onap.policy.models.base.PfUtils;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * This class is used to send PropertiesUpdate messages to participants.
+ */
+@Component
+@AllArgsConstructor
+public class AcElementPropertiesPublisher extends AbstractParticipantPublisher<PropertiesUpdate> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionDeployPublisher.class);
+
+ /**
+ * Send ACElementPropertiesUpdate to Participant.
+ *
+ * @param automationComposition the AutomationComposition
+ */
+ @Timed(value = "publisher.properties_update",
+ description = "AC Element Properties Update published")
+ public void send(AutomationComposition automationComposition) {
+ Map<UUID, List<AcElementDeploy>> map = new HashMap<>();
+ for (var element : automationComposition.getElements().values()) {
+ var acElementDeploy = new AcElementDeploy();
+ acElementDeploy.setId(element.getId());
+ acElementDeploy.setDefinition(new ToscaConceptIdentifier(element.getDefinition()));
+ acElementDeploy.setOrderedState(DeployOrder.UPDATE);
+ acElementDeploy.setProperties(PfUtils.mapMap(element.getProperties(), UnaryOperator.identity()));
+
+ map.putIfAbsent(element.getParticipantId(), new ArrayList<>());
+ map.get(element.getParticipantId()).add(acElementDeploy);
+ }
+ List<ParticipantDeploy> participantDeploys = new ArrayList<>();
+ for (var entry : map.entrySet()) {
+ var participantDeploy = new ParticipantDeploy();
+ participantDeploy.setParticipantId(entry.getKey());
+ participantDeploy.setAcElementList(entry.getValue());
+ participantDeploys.add(participantDeploy);
+ }
+
+ var propertiesUpdate = new PropertiesUpdate();
+ propertiesUpdate.setCompositionId(automationComposition.getCompositionId());
+ propertiesUpdate.setAutomationCompositionId(automationComposition.getInstanceId());
+ propertiesUpdate.setMessageId(UUID.randomUUID());
+ propertiesUpdate.setTimestamp(Instant.now());
+ propertiesUpdate.setParticipantUpdatesList(participantDeploys);
+
+ LOGGER.debug("AC Element properties update sent {}", propertiesUpdate);
+ super.send(propertiesUpdate);
+ }
+}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java
index faf356c22..54a0c9613 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java
@@ -313,22 +313,6 @@ class AutomationCompositionInstantiationProviderTest {
}
@Test
- void testUpdateBadRequest() {
- var automationComposition = InstantiationUtils
- .getAutomationCompositionFromResource(AC_INSTANTIATION_AC_DEFINITION_NOT_FOUND_JSON, "AcNotFound");
-
- var acProvider = mock(AutomationCompositionProvider.class);
- automationComposition.setDeployState(DeployState.DEPLOYED);
- when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
- .thenReturn(automationComposition);
- var provider = new AutomationCompositionInstantiationProvider(acProvider,
- mock(AcDefinitionProvider.class), null, null);
-
- assertThatThrownBy(() -> provider.updateAutomationComposition(automationComposition.getCompositionId(),
- automationComposition)).hasMessageMatching("Not allow to update for state in DEPLOYED");
- }
-
- @Test
void testCompositionInstanceState() {
var acDefinitionProvider = mock(AcDefinitionProvider.class);
var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.COMMISSIONED);
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java
index c61984b01..e763127cc 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java
@@ -33,6 +33,7 @@ import java.util.Optional;
import java.util.UUID;
import org.junit.jupiter.api.Test;
import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.AcElementPropertiesPublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionDeployPublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionStateChangePublisher;
import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
@@ -59,7 +60,8 @@ class SupervisionAcHandlerTest {
var handler = new SupervisionAcHandler(automationCompositionProvider,
mock(AutomationCompositionDeployPublisher.class),
- mock(AutomationCompositionStateChangePublisher.class));
+ mock(AutomationCompositionStateChangePublisher.class),
+ mock(AcElementPropertiesPublisher.class));
var automationCompositionAckMessage =
new AutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
@@ -97,7 +99,8 @@ class SupervisionAcHandlerTest {
var handler = new SupervisionAcHandler(automationCompositionProvider,
mock(AutomationCompositionDeployPublisher.class),
- mock(AutomationCompositionStateChangePublisher.class));
+ mock(AutomationCompositionStateChangePublisher.class),
+ mock(AcElementPropertiesPublisher.class));
handler.handleAutomationCompositionUpdateAckMessage(automationCompositionAckMessage);
@@ -110,7 +113,7 @@ class SupervisionAcHandlerTest {
var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
var handler = new SupervisionAcHandler(automationCompositionProvider,
mock(AutomationCompositionDeployPublisher.class),
- acStateChangePublisher);
+ acStateChangePublisher, mock(AcElementPropertiesPublisher.class));
var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
var automationComposition =
@@ -127,7 +130,7 @@ class SupervisionAcHandlerTest {
var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
var handler = new SupervisionAcHandler(automationCompositionProvider,
mock(AutomationCompositionDeployPublisher.class),
- acStateChangePublisher);
+ acStateChangePublisher, mock(AcElementPropertiesPublisher.class));
var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
var automationComposition =
@@ -144,7 +147,7 @@ class SupervisionAcHandlerTest {
var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
var handler = new SupervisionAcHandler(automationCompositionProvider,
mock(AutomationCompositionDeployPublisher.class),
- acStateChangePublisher);
+ acStateChangePublisher, mock(AcElementPropertiesPublisher.class));
var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
var automationComposition =