From 461bbdb67733552e78037bd96ca7efdfd3015e25 Mon Sep 17 00:00:00 2001 From: rameshiyer27 Date: Thu, 18 May 2023 16:47:10 +0100 Subject: 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 Change-Id: Ic35fba669b5ffcf2c75d6deaa8c309d58e4026f0 --- .../api/AutomationCompositionElementListener.java | 5 ++ .../comm/AcPropertyUpdateListener.java | 49 +++++++++++ .../handler/AutomationCompositionHandler.java | 95 ++++++++++++++++++---- .../intermediary/handler/ParticipantHandler.java | 14 ++++ 4 files changed, 149 insertions(+), 14 deletions(-) create mode 100644 participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AcPropertyUpdateListener.java (limited to 'participant/participant-intermediary/src/main/java/org') diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/AutomationCompositionElementListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/AutomationCompositionElementListener.java index d6ef80fbe..c8fd91d69 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/AutomationCompositionElementListener.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/AutomationCompositionElementListener.java @@ -62,4 +62,9 @@ public interface AutomationCompositionElementListener { throws PfModelException { // default Delete Operation } + + public default void update(UUID automationCompositionId, AcElementDeploy element, Map properties) + throws PfModelException { + // default update Operation + } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AcPropertyUpdateListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AcPropertyUpdateListener.java new file mode 100644 index 000000000..d6f1970d7 --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AcPropertyUpdateListener.java @@ -0,0 +1,49 @@ +/*- + * ============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.participant.intermediary.comm; + +import org.onap.policy.clamp.acm.participant.intermediary.handler.ParticipantHandler; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionDeploy; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.PropertiesUpdate; +import org.springframework.stereotype.Component; + +/** + * Listener for AC Element property update messages sent by ACM. + */ +@Component +public class AcPropertyUpdateListener extends ParticipantListener { + + /** + * Constructs the object. + * + * @param participantHandler the handler for managing the state of the participant + */ + public AcPropertyUpdateListener(final ParticipantHandler participantHandler) { + super(PropertiesUpdate.class, participantHandler, + participantHandler::handleAcPropertyUpdate); + } + + @Override + public String getType() { + return ParticipantMessageType.PROPERTIES_UPDATE.name(); + } +} 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 d33498518..9087054fe 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 @@ -49,6 +49,7 @@ import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCom import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionStateChange; import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType; import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus; +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.clamp.models.acm.messages.rest.instantiation.LockOrder; import org.onap.policy.clamp.models.acm.persistence.provider.AcInstanceStateResolver; @@ -261,6 +262,33 @@ public class AutomationCompositionHandler { } } + /** + * Handle a automation composition properties update message. + * + * @param updateMsg the properties update message + * @param acElementDefinitions the list of AutomationCompositionElementDefinition + */ + public void handleAcPropertyUpdate(PropertiesUpdate updateMsg, + List acElementDefinitions) { + + if (updateMsg.getParticipantUpdatesList().isEmpty()) { + LOGGER.warn("No AutomationCompositionElement updates in message {}", + updateMsg.getAutomationCompositionId()); + return; + } + + for (var participantDeploy : updateMsg.getParticipantUpdatesList()) { + if (participantId.equals(participantDeploy.getParticipantId())) { + + initializeDeploy(updateMsg.getMessageId(), updateMsg.getAutomationCompositionId(), + participantDeploy, DeployState.UPDATING); + + callParticipantUpdateProperty(participantDeploy.getAcElementList(), acElementDefinitions, + updateMsg.getAutomationCompositionId()); + } + } + } + /** * Handle a automation composition Deploy message. * @@ -280,28 +308,34 @@ public class AutomationCompositionHandler { if (participantId.equals(participantDeploy.getParticipantId())) { if (updateMsg.isFirstStartPhase()) { initializeDeploy(updateMsg.getMessageId(), updateMsg.getAutomationCompositionId(), - participantDeploy); + participantDeploy, DeployState.DEPLOYING); } - callParticipanDeploy(participantDeploy.getAcElementList(), acElementDefinitions, + callParticipantDeploy(participantDeploy.getAcElementList(), acElementDefinitions, updateMsg.getStartPhase(), updateMsg.getAutomationCompositionId()); } } } - private void initializeDeploy(UUID messageId, UUID instanceId, ParticipantDeploy participantDeploy) { - var automationComposition = new AutomationComposition(); - automationComposition.setInstanceId(instanceId); - var acElements = storeElementsOnThisParticipant(participantDeploy); - automationComposition.setElements(prepareAcElementMap(acElements)); - automationCompositionMap.put(instanceId, automationComposition); + private void initializeDeploy(UUID messageId, UUID instanceId, ParticipantDeploy participantDeploy, + DeployState deployState) { + if (automationCompositionMap.containsKey(instanceId)) { + updateExistingElementsOnThisParticipant(instanceId, participantDeploy, deployState); + } else { + var automationComposition = new AutomationComposition(); + automationComposition.setInstanceId(instanceId); + var acElements = storeElementsOnThisParticipant(participantDeploy, deployState); + automationComposition.setElements(prepareAcElementMap(acElements)); + automationCompositionMap.put(instanceId, automationComposition); + } } - private void callParticipanDeploy(List acElements, - List acElementDefinitions, Integer startPhaseMsg, - UUID automationCompositionId) { + private void callParticipantDeploy(List acElements, + List acElementDefinitions, + Integer startPhaseMsg, UUID automationCompositionId) { try { for (var element : acElements) { - var acElementNodeTemplate = getAcElementNodeTemplate(acElementDefinitions, element.getDefinition()); + var acElementNodeTemplate = getAcElementNodeTemplate(acElementDefinitions, + element.getDefinition()); if (acElementNodeTemplate != null) { int startPhase = ParticipantUtils.findStartPhase(acElementNodeTemplate.getProperties()); if (startPhaseMsg.equals(startPhase)) { @@ -319,6 +353,27 @@ public class AutomationCompositionHandler { } + private void callParticipantUpdateProperty(List acElements, + List acElementDefinitions, + UUID automationCompositionId) { + try { + for (var element : acElements) { + var acElementNodeTemplate = getAcElementNodeTemplate(acElementDefinitions, + element.getDefinition()); + if (acElementNodeTemplate != null) { + for (var acElementListener : listeners) { + var map = new HashMap<>(acElementNodeTemplate.getProperties()); + map.putAll(element.getProperties()); + acElementListener.update(automationCompositionId, element, map); + } + } + } + } catch (PfModelException e) { + LOGGER.error("Automation composition element update failed for {} {}", automationCompositionId, e); + } + + } + private ToscaNodeTemplate getAcElementNodeTemplate( List acElementDefinitions, ToscaConceptIdentifier acElementDefId) { @@ -330,20 +385,32 @@ public class AutomationCompositionHandler { return null; } - private List storeElementsOnThisParticipant(ParticipantDeploy participantDeploy) { + private List storeElementsOnThisParticipant(ParticipantDeploy participantDeploy, + DeployState deployState) { List acElementList = new ArrayList<>(); for (var element : participantDeploy.getAcElementList()) { var acElement = new AutomationCompositionElement(); acElement.setId(element.getId()); acElement.setParticipantId(participantDeploy.getParticipantId()); acElement.setDefinition(element.getDefinition()); - acElement.setDeployState(DeployState.DEPLOYING); + acElement.setDeployState(deployState); acElement.setLockState(LockState.NONE); acElementList.add(acElement); } return acElementList; } + private void updateExistingElementsOnThisParticipant( + UUID instanceId, ParticipantDeploy participantDeploy, DeployState deployState) { + + Map elementList = automationCompositionMap.get(instanceId).getElements(); + for (var element : participantDeploy.getAcElementList()) { + automationCompositionMap.get(instanceId).getElements().get(element.getId()).getProperties() + .putAll(element.getProperties()); + automationCompositionMap.get(instanceId).getElements().get(element.getId()).setDeployState(deployState); + } + } + private Map prepareAcElementMap(List acElements) { Map acElementMap = new LinkedHashMap<>(); for (var element : acElements) { diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java index 44a988a27..9e1216cec 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java @@ -47,6 +47,7 @@ import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRe import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegisterAck; import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus; import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatusReq; +import org.onap.policy.clamp.models.acm.messages.dmaap.participant.PropertiesUpdate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -120,6 +121,19 @@ public class ParticipantHandler { acElementDefsMap.get(stateChangeMsg.getCompositionId())); } + /** + * Handle a automation composition property update message. + * + * @param propertyUpdateMsg the property update message + */ + @Timed( + value = "listener.properties_update", + description = "PROPERTIES_UPDATE message received") + public void handleAcPropertyUpdate(PropertiesUpdate propertyUpdateMsg) { + automationCompositionHandler.handleAcPropertyUpdate(propertyUpdateMsg, + acElementDefsMap.get(propertyUpdateMsg.getCompositionId())); + } + /** * Check if a participant message applies to this participant handler. * -- cgit 1.2.3-korg