2  * ============LICENSE_START=======================================================
 
   3  *  Copyright (C) 2023-2025 OpenInfra Foundation Europe. All rights reserved.
 
   4  * ================================================================================
 
   5  * Licensed under the Apache License, Version 2.0 (the "License");
 
   6  * you may not use this file except in compliance with the License.
 
   7  * You may obtain a copy of the License at
 
   9  *      http://www.apache.org/licenses/LICENSE-2.0
 
  11  * Unless required by applicable law or agreed to in writing, software
 
  12  * distributed under the License is distributed on an "AS IS" BASIS,
 
  13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  14  * See the License for the specific language governing permissions and
 
  15  * limitations under the License.
 
  17  * SPDX-License-Identifier: Apache-2.0
 
  18  * ============LICENSE_END=========================================================
 
  21 package org.onap.policy.clamp.acm.participant.intermediary.handler.cache;
 
  23 import java.util.HashMap;
 
  24 import java.util.LinkedHashMap;
 
  25 import java.util.List;
 
  27 import java.util.UUID;
 
  28 import java.util.concurrent.ConcurrentHashMap;
 
  30 import lombok.NonNull;
 
  32 import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto;
 
  33 import org.onap.policy.clamp.acm.participant.intermediary.api.ElementState;
 
  34 import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto;
 
  35 import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantParameters;
 
  36 import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
 
  37 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
 
  38 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
 
  39 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
 
  40 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 
  41 import org.onap.policy.clamp.models.acm.concepts.LockState;
 
  42 import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy;
 
  43 import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc;
 
  44 import org.onap.policy.clamp.models.acm.concepts.ParticipantSupportedElementType;
 
  45 import org.onap.policy.clamp.models.acm.concepts.SubState;
 
  46 import org.onap.policy.models.base.PfUtils;
 
  47 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 
  48 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
 
  49 import org.springframework.stereotype.Component;
 
  52 public class CacheProvider {
 
  55     private final UUID participantId;
 
  59     private boolean registered = false;
 
  62     private final UUID replicaId;
 
  64     private final List<ParticipantSupportedElementType> supportedAcElementTypes;
 
  67     private final Map<UUID, AutomationComposition> automationCompositions = new ConcurrentHashMap<>();
 
  70     private final Map<UUID, AcDefinition> acElementsDefinitions = new ConcurrentHashMap<>();
 
  73     private final Map<UUID, UUID> msgIdentification = new ConcurrentHashMap<>();
 
  76     private final Map<UUID, AutomationCompositionMsg<?>> messagesOnHold = new HashMap<>();
 
  81      * @param parameters the parameters of the participant
 
  83     public CacheProvider(ParticipantParameters parameters) {
 
  84         this.participantId = parameters.getIntermediaryParameters().getParticipantId();
 
  85         this.supportedAcElementTypes = parameters.getIntermediaryParameters().getParticipantSupportedElementTypes();
 
  86         this.replicaId = UUID.randomUUID();
 
  89     public List<ParticipantSupportedElementType> getSupportedAcElementTypes() {
 
  90         return PfUtils.mapList(supportedAcElementTypes, ParticipantSupportedElementType::new);
 
  94      * Get AutomationComposition by id.
 
  96      * @param automationCompositionId the AutomationComposition Id
 
  97      * @return the AutomationComposition
 
  99     public AutomationComposition getAutomationComposition(@NonNull UUID automationCompositionId) {
 
 100         return automationCompositions.get(automationCompositionId);
 
 104      * Remove AutomationComposition.
 
 106      * @param automationCompositionId the AutomationComposition Id
 
 108     public void removeAutomationComposition(@NonNull UUID automationCompositionId) {
 
 109         automationCompositions.remove(automationCompositionId);
 
 113      * Add ElementDefinition.
 
 115      * @param compositionId the composition Id
 
 116      * @param list the list of AutomationCompositionElementDefinition to add
 
 117      * @param revisionId the last Update
 
 119     public void addElementDefinition(@NonNull UUID compositionId, List<AutomationCompositionElementDefinition> list,
 
 121         var acDefinition = new AcDefinition();
 
 122         acDefinition.setCompositionId(compositionId);
 
 123         acDefinition.setRevisionId(revisionId);
 
 124         for (var acElementDefinition : list) {
 
 125             if (acElementDefinition.getAutomationCompositionElementToscaNodeTemplate() == null) {
 
 126                 acElementDefinition.setAutomationCompositionElementToscaNodeTemplate(new ToscaNodeTemplate());
 
 128             if (acElementDefinition.getAutomationCompositionElementToscaNodeTemplate().getProperties() == null) {
 
 129                 acElementDefinition.getAutomationCompositionElementToscaNodeTemplate().setProperties(new HashMap<>());
 
 131             acDefinition.getElements().put(acElementDefinition.getAcElementDefinitionId(), acElementDefinition);
 
 133         acElementsDefinitions.put(compositionId, acDefinition);
 
 136     public void removeElementDefinition(@NonNull UUID compositionId) {
 
 137         acElementsDefinitions.remove(compositionId);
 
 141      * Get CommonProperties.
 
 143      * @param instanceId the Automation Composition Id
 
 144      * @param acElementId the Automation Composition Element Id
 
 145      * @return the common Properties as Map
 
 147     public Map<String, Object> getCommonProperties(@NonNull UUID instanceId, @NonNull UUID acElementId) {
 
 148         var automationComposition = automationCompositions.get(instanceId);
 
 149         var element = automationComposition.getElements().get(acElementId);
 
 150         return getCommonProperties(automationComposition.getCompositionId(), element.getDefinition());
 
 154      * Get CommonProperties.
 
 156      * @param compositionId the composition Id
 
 157      * @param definition the AutomationCompositionElementDefinition Id
 
 158      * @return the common Properties as Map
 
 160     public Map<String, Object> getCommonProperties(@NonNull UUID compositionId,
 
 161         @NonNull ToscaConceptIdentifier definition) {
 
 162         var map = acElementsDefinitions.get(compositionId).getElements().get(definition);
 
 163         return map != null ? map.getAutomationCompositionElementToscaNodeTemplate().getProperties() : new HashMap<>();
 
 167      * Initialize an AutomationComposition from a ParticipantDeploy.
 
 169      * @param compositionId the composition Id
 
 170      * @param instanceId the Automation Composition Id
 
 171      * @param participantDeploy the ParticipantDeploy
 
 172      * @param revisionId the identification of the last update
 
 174     public void initializeAutomationComposition(@NonNull UUID compositionId, @NonNull UUID instanceId,
 
 175             ParticipantDeploy participantDeploy, UUID revisionId) {
 
 176         initializeAutomationComposition(compositionId, instanceId, participantDeploy,
 
 177             DeployState.DEPLOYING, SubState.NONE, revisionId);
 
 181      * Initialize an AutomationComposition from a ParticipantDeploy.
 
 183      * @param compositionId the composition Id
 
 184      * @param instanceId the Automation Composition Id
 
 185      * @param participantDeploy the ParticipantDeploy
 
 186      * @param deployState the DeployState
 
 187      * @param subState the SubState
 
 188      * @param revisionId the identification of the last update
 
 190     public void initializeAutomationComposition(@NonNull UUID compositionId, @NonNull UUID instanceId,
 
 191             ParticipantDeploy participantDeploy, DeployState deployState, SubState subState, UUID revisionId) {
 
 192         var acLast = automationCompositions.get(instanceId);
 
 193         Map<UUID, AutomationCompositionElement> acElementMap = new LinkedHashMap<>();
 
 194         for (var element : participantDeploy.getAcElementList()) {
 
 195             var acElement = createAutomationCompositionElement(element);
 
 196             acElement.setParticipantId(getParticipantId());
 
 197             acElement.setDeployState(deployState);
 
 198             acElement.setSubState(subState);
 
 199             var acElementLast = acLast != null ? acLast.getElements().get(element.getId()) : null;
 
 200             if (acElementLast != null) {
 
 201                 acElement.setOutProperties(acElementLast.getOutProperties());
 
 202                 acElement.setOperationalState(acElementLast.getOperationalState());
 
 203                 acElement.setUseState(acElementLast.getUseState());
 
 205             acElementMap.put(element.getId(), acElement);
 
 207         var automationComposition = new AutomationComposition();
 
 208         automationComposition.setCompositionId(compositionId);
 
 209         automationComposition.setInstanceId(instanceId);
 
 210         automationComposition.setElements(acElementMap);
 
 211         automationComposition.setDeployState(deployState);
 
 212         automationComposition.setSubState(subState);
 
 213         automationComposition.setRevisionId(revisionId);
 
 214         automationCompositions.put(instanceId, automationComposition);
 
 218      * Initialize an AutomationComposition from a ParticipantRestartAc.
 
 220      * @param compositionId the composition Id
 
 221      * @param participantRestartAc the ParticipantRestartAc
 
 223     public void initializeAutomationComposition(@NonNull UUID compositionId,
 
 224             ParticipantRestartAc participantRestartAc) {
 
 225         Map<UUID, AutomationCompositionElement> acElementMap = new LinkedHashMap<>();
 
 226         for (var element : participantRestartAc.getAcElementList()) {
 
 227             if (!getParticipantId().equals(element.getParticipantId())) {
 
 230             var acElement = new AutomationCompositionElement();
 
 231             acElement.setId(element.getId());
 
 232             acElement.setParticipantId(getParticipantId());
 
 233             acElement.setDefinition(element.getDefinition());
 
 234             acElement.setDeployState(element.getDeployState());
 
 235             acElement.setLockState(element.getLockState());
 
 236             acElement.setSubState(SubState.NONE);
 
 237             acElement.setOperationalState(element.getOperationalState());
 
 238             acElement.setUseState(element.getUseState());
 
 239             acElement.setProperties(element.getProperties());
 
 240             acElement.setOutProperties(element.getOutProperties());
 
 241             acElementMap.put(element.getId(), acElement);
 
 244         var automationComposition = new AutomationComposition();
 
 245         automationComposition.setCompositionId(compositionId);
 
 246         automationComposition.setDeployState(participantRestartAc.getDeployState());
 
 247         automationComposition.setLockState(participantRestartAc.getLockState());
 
 248         automationComposition.setInstanceId(participantRestartAc.getAutomationCompositionId());
 
 249         automationComposition.setElements(acElementMap);
 
 250         automationComposition.setStateChangeResult(participantRestartAc.getStateChangeResult());
 
 251         automationComposition.setRevisionId(participantRestartAc.getRevisionId());
 
 252         automationCompositions.put(automationComposition.getInstanceId(), automationComposition);
 
 256      * Create AutomationCompositionElement to save in memory.
 
 258      * @param element AcElementDeploy
 
 259      * @return a new AutomationCompositionElement
 
 261     public static AutomationCompositionElement createAutomationCompositionElement(AcElementDeploy element) {
 
 262         var acElement = new AutomationCompositionElement();
 
 263         acElement.setId(element.getId());
 
 264         acElement.setDefinition(element.getDefinition());
 
 265         acElement.setProperties(element.getProperties());
 
 266         acElement.setSubState(SubState.NONE);
 
 267         acElement.setLockState(LockState.LOCKED);
 
 272      * Create CompositionElementDto.
 
 274      * @param compositionId the composition Id
 
 275      * @param element AutomationComposition Element
 
 276      * @return the CompositionElementDto
 
 278     public CompositionElementDto createCompositionElementDto(UUID compositionId, AutomationCompositionElement element) {
 
 279         var acDefinition = acElementsDefinitions.get(compositionId);
 
 280         var acDefinitionElement = acDefinition.getElements().get(element.getDefinition());
 
 282         return (acDefinitionElement != null) ? new CompositionElementDto(compositionId, element.getDefinition(),
 
 283                 acDefinitionElement.getAutomationCompositionElementToscaNodeTemplate().getProperties(),
 
 284                 acDefinitionElement.getOutProperties()) :
 
 285             new CompositionElementDto(compositionId, element.getDefinition(),
 
 286                 Map.of(), Map.of(), ElementState.NOT_PRESENT);
 
 290      * Get a Map of CompositionElementDto by elementId from the elements of an AutomationComposition.
 
 292      * @param automationComposition the AutomationComposition
 
 293      * @param compositionId the compositionId
 
 294      * @return the Map of CompositionElementDto
 
 296     public Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition,
 
 297             UUID compositionId) {
 
 298         var acDefinition = acElementsDefinitions.get(compositionId);
 
 299         Map<UUID, CompositionElementDto> map = new HashMap<>();
 
 300         for (var element : automationComposition.getElements().values()) {
 
 301             var acDefinitionElement = acDefinition.getElements().get(element.getDefinition());
 
 302             var compositionElement = (acDefinitionElement != null)
 
 303                     ? new CompositionElementDto(compositionId, element.getDefinition(),
 
 304                     acDefinitionElement.getAutomationCompositionElementToscaNodeTemplate().getProperties(),
 
 305                     acDefinitionElement.getOutProperties()) :
 
 306                     new CompositionElementDto(compositionId, element.getDefinition(),
 
 307                             Map.of(), Map.of(), ElementState.NOT_PRESENT);
 
 308             map.put(element.getId(), compositionElement);
 
 313     public Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition) {
 
 314         return getCompositionElementDtoMap(automationComposition, automationComposition.getCompositionId());
 
 318      * Get a Map of InstanceElementDto by elementId from the elements of an AutomationComposition.
 
 320      * @param automationComposition the AutomationComposition
 
 321      * @return the Map of InstanceElementDto
 
 323     public Map<UUID, InstanceElementDto> getInstanceElementDtoMap(AutomationComposition automationComposition) {
 
 324         Map<UUID, InstanceElementDto> map = new HashMap<>();
 
 325         for (var element : automationComposition.getElements().values()) {
 
 326             var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(),
 
 327                     element.getProperties(), element.getOutProperties());
 
 328             map.put(element.getId(), instanceElement);
 
 334      * Create a new InstanceElementDto record with state New.
 
 336      * @param instanceElement the InstanceElementDto
 
 337      * @return a new InstanceElementDto
 
 339     public static InstanceElementDto changeStateToNew(InstanceElementDto instanceElement) {
 
 340         return new InstanceElementDto(instanceElement.instanceId(), instanceElement.elementId(),
 
 341                 instanceElement.inProperties(), instanceElement.outProperties(), ElementState.NEW);
 
 345      * Create a new CompositionElementDto record with state New.
 
 347      * @param compositionElement the CompositionElementDto
 
 348      * @return a new CompositionElementDto
 
 350     public static CompositionElementDto changeStateToNew(CompositionElementDto compositionElement) {
 
 351         return new CompositionElementDto(compositionElement.compositionId(), compositionElement.elementDefinitionId(),
 
 352                 compositionElement.inProperties(), compositionElement.outProperties(), ElementState.NEW);
 
 356      * Check composition is present and compare the last update.
 
 358      * @param compositionId the instanceId
 
 359      * @param revisionId the last Update
 
 360      * @return true if the composition is updated
 
 362     public boolean isCompositionDefinitionUpdated(UUID compositionId, UUID revisionId) {
 
 363         if (revisionId == null) {
 
 367         var acDefinition = acElementsDefinitions.get(compositionId);
 
 368         if (acDefinition == null) {
 
 371         return revisionId.equals(acDefinition.getRevisionId());
 
 375      * Check instance is present and compare the last update.
 
 377      * @param instanceId the instanceId
 
 378      * @param revisionId the last Update
 
 379      * @return true if the instance is updated
 
 381     public boolean isInstanceUpdated(UUID instanceId, UUID revisionId) {
 
 382         if (revisionId == null) {
 
 386         var automationComposition = automationCompositions.get(instanceId);
 
 387         if (automationComposition == null) {
 
 390         return revisionId.equals(automationComposition.getRevisionId());