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.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51 import org.springframework.stereotype.Component;
54 public class CacheProvider {
56 private static final Logger LOGGER = LoggerFactory.getLogger(CacheProvider.class);
59 private final UUID participantId;
63 private boolean registered = false;
66 private final UUID replicaId;
68 private final List<ParticipantSupportedElementType> supportedAcElementTypes;
71 private final Map<UUID, AutomationComposition> automationCompositions = new ConcurrentHashMap<>();
74 private final Map<UUID, AcDefinition> acElementsDefinitions = new ConcurrentHashMap<>();
77 private final Map<UUID, UUID> msgIdentification = new ConcurrentHashMap<>();
80 private final Map<UUID, AutomationCompositionMsg<?>> messagesOnHold = new HashMap<>();
85 * @param parameters the parameters of the participant
87 public CacheProvider(ParticipantParameters parameters) {
88 this.participantId = parameters.getIntermediaryParameters().getParticipantId();
89 this.supportedAcElementTypes = parameters.getIntermediaryParameters().getParticipantSupportedElementTypes();
90 this.replicaId = UUID.randomUUID();
93 public List<ParticipantSupportedElementType> getSupportedAcElementTypes() {
94 return PfUtils.mapList(supportedAcElementTypes, ParticipantSupportedElementType::new);
98 * Get AutomationComposition by id.
100 * @param automationCompositionId the AutomationComposition Id
101 * @return the AutomationComposition
103 public AutomationComposition getAutomationComposition(@NonNull UUID automationCompositionId) {
104 return automationCompositions.get(automationCompositionId);
108 * Remove AutomationComposition.
110 * @param automationCompositionId the AutomationComposition Id
112 public void removeAutomationComposition(@NonNull UUID automationCompositionId) {
113 automationCompositions.remove(automationCompositionId);
117 * Add ElementDefinition.
119 * @param compositionId the composition Id
120 * @param list the list of AutomationCompositionElementDefinition to add
121 * @param revisionId the last Update
123 public void addElementDefinition(@NonNull UUID compositionId, List<AutomationCompositionElementDefinition> list,
125 var acDefinition = new AcDefinition();
126 acDefinition.setCompositionId(compositionId);
127 acDefinition.setRevisionId(revisionId);
128 for (var acElementDefinition : list) {
129 if (acElementDefinition.getAutomationCompositionElementToscaNodeTemplate() == null) {
130 acElementDefinition.setAutomationCompositionElementToscaNodeTemplate(new ToscaNodeTemplate());
132 if (acElementDefinition.getAutomationCompositionElementToscaNodeTemplate().getProperties() == null) {
133 acElementDefinition.getAutomationCompositionElementToscaNodeTemplate().setProperties(new HashMap<>());
135 acDefinition.getElements().put(acElementDefinition.getAcElementDefinitionId(), acElementDefinition);
137 acElementsDefinitions.put(compositionId, acDefinition);
138 LOGGER.info("Updated cache for the composition id {}", compositionId);
141 public void removeElementDefinition(@NonNull UUID compositionId) {
142 acElementsDefinitions.remove(compositionId);
146 * Get CommonProperties.
148 * @param instanceId the Automation Composition Id
149 * @param acElementId the Automation Composition Element Id
150 * @return the common Properties as Map
152 public Map<String, Object> getCommonProperties(@NonNull UUID instanceId, @NonNull UUID acElementId) {
153 var automationComposition = automationCompositions.get(instanceId);
154 var element = automationComposition.getElements().get(acElementId);
155 return getCommonProperties(automationComposition.getCompositionId(), element.getDefinition());
159 * Get CommonProperties.
161 * @param compositionId the composition Id
162 * @param definition the AutomationCompositionElementDefinition Id
163 * @return the common Properties as Map
165 public Map<String, Object> getCommonProperties(@NonNull UUID compositionId,
166 @NonNull ToscaConceptIdentifier definition) {
167 var acDefinition = acElementsDefinitions.get(compositionId);
168 if (acDefinition == null) {
169 return new HashMap<>();
171 var map = acDefinition.getElements().get(definition);
172 return map != null ? map.getAutomationCompositionElementToscaNodeTemplate().getProperties() : new HashMap<>();
176 * Initialize an AutomationComposition from a ParticipantDeploy.
178 * @param compositionId the composition Id
179 * @param instanceId the Automation Composition Id
180 * @param participantDeploy the ParticipantDeploy
181 * @param revisionId the identification of the last update
183 public void initializeAutomationComposition(@NonNull UUID compositionId, @NonNull UUID instanceId,
184 ParticipantDeploy participantDeploy, UUID revisionId) {
185 initializeAutomationComposition(compositionId, null, instanceId, participantDeploy,
186 DeployState.DEPLOYING, SubState.NONE, revisionId);
191 * Initialize an AutomationComposition from a ParticipantDeploy.
193 * @param compositionId the composition Id
194 * @param instanceId the Automation Composition Id
195 * @param participantDeploy the ParticipantDeploy
196 * @param deployState the DeployState
197 * @param subState the SubState
198 * @param revisionId the identification of the last update
200 public void initializeAutomationComposition(@NonNull UUID compositionId, UUID compositionTargetId,
201 @NonNull UUID instanceId,
202 ParticipantDeploy participantDeploy, DeployState deployState, SubState subState, UUID revisionId) {
204 var automationComposition = createAcInstance(compositionId, compositionTargetId, instanceId, participantDeploy,
205 deployState, subState, revisionId);
207 automationCompositions.put(instanceId, automationComposition);
208 LOGGER.info("Initialized participant cache for the {} operation of the instance {}", deployState, instanceId);
213 * Initialize an AutomationComposition from a ParticipantRestartAc.
215 * @param compositionId the composition Id
216 * @param participantRestartAc the ParticipantRestartAc
218 public void initializeAutomationComposition(@NonNull UUID compositionId,
219 ParticipantRestartAc participantRestartAc) {
220 Map<UUID, AutomationCompositionElement> acElementMap = new LinkedHashMap<>();
221 for (var element : participantRestartAc.getAcElementList()) {
222 if (!getParticipantId().equals(element.getParticipantId())) {
225 var acElement = new AutomationCompositionElement();
226 acElement.setId(element.getId());
227 acElement.setParticipantId(getParticipantId());
228 acElement.setDefinition(element.getDefinition());
229 acElement.setDeployState(element.getDeployState());
230 acElement.setLockState(element.getLockState());
231 acElement.setSubState(SubState.NONE);
232 acElement.setOperationalState(element.getOperationalState());
233 acElement.setUseState(element.getUseState());
234 acElement.setProperties(element.getProperties());
235 acElement.setOutProperties(element.getOutProperties());
236 acElement.setMigrationState(element.getMigrationState());
237 acElementMap.put(element.getId(), acElement);
239 var automationComposition = new AutomationComposition();
240 automationComposition.setCompositionId(compositionId);
241 automationComposition.setCompositionTargetId(participantRestartAc.getCompositionTargetId());
242 automationComposition.setDeployState(participantRestartAc.getDeployState());
243 automationComposition.setLockState(participantRestartAc.getLockState());
244 automationComposition.setInstanceId(participantRestartAc.getAutomationCompositionId());
245 automationComposition.setElements(acElementMap);
246 automationComposition.setStateChangeResult(participantRestartAc.getStateChangeResult());
247 automationComposition.setRevisionId(participantRestartAc.getRevisionId());
248 automationCompositions.put(automationComposition.getInstanceId(), automationComposition);
249 LOGGER.info("Updated participant cache for the instance id {}",
250 participantRestartAc.getAutomationCompositionId());
254 * Create an AutomationComposition.
255 * @param compositionId compositionId
256 * @param compositionTargetId compositionTargetId
257 * @param instanceId instanceId
258 * @param participantDeploy participantDeploy
259 * @param deployState deployState
260 * @param subState subState
261 * @param revisionId revisionId
262 * @return AutomationComposition
264 public AutomationComposition createAcInstance(@NonNull UUID compositionId, UUID compositionTargetId,
265 @NonNull UUID instanceId, ParticipantDeploy participantDeploy,
266 DeployState deployState, SubState subState, UUID revisionId) {
267 var acLast = automationCompositions.get(instanceId);
268 Map<UUID, AutomationCompositionElement> acElementMap = new LinkedHashMap<>();
269 for (var element : participantDeploy.getAcElementList()) {
270 var acElement = createAutomationCompositionElement(element);
271 acElement.setParticipantId(getParticipantId());
272 acElement.setDeployState(deployState);
273 acElement.setSubState(subState);
274 var acElementLast = acLast != null ? acLast.getElements().get(element.getId()) : null;
275 if (acElementLast != null) {
276 acElement.setOutProperties(acElementLast.getOutProperties());
277 acElement.setOperationalState(acElementLast.getOperationalState());
278 acElement.setUseState(acElementLast.getUseState());
280 acElementMap.put(element.getId(), acElement);
282 var automationComposition = acLast != null ? acLast : new AutomationComposition();
283 automationComposition.setCompositionId(compositionId);
284 automationComposition.setInstanceId(instanceId);
285 if (acLast != null) {
286 automationComposition.getElements().putAll(acElementMap);
288 automationComposition.setElements(acElementMap);
290 automationComposition.setDeployState(deployState);
291 automationComposition.setSubState(subState);
292 automationComposition.setRevisionId(revisionId);
293 if (compositionTargetId != null) {
294 automationComposition.setCompositionTargetId(compositionTargetId);
297 return automationComposition;
301 * Create AutomationCompositionElement to save in memory.
303 * @param element AcElementDeploy
304 * @return a new AutomationCompositionElement
306 public static AutomationCompositionElement createAutomationCompositionElement(AcElementDeploy element) {
307 var acElement = new AutomationCompositionElement();
308 acElement.setId(element.getId());
309 acElement.setDefinition(element.getDefinition());
310 acElement.setProperties(element.getProperties());
311 acElement.setSubState(SubState.NONE);
312 acElement.setLockState(LockState.LOCKED);
313 acElement.setMigrationState(element.getMigrationState());
318 * Create CompositionElementDto.
320 * @param compositionId the composition Id
321 * @param element AutomationComposition Element
322 * @return the CompositionElementDto
324 public CompositionElementDto createCompositionElementDto(UUID compositionId, AutomationCompositionElement element) {
325 var acDefinition = acElementsDefinitions.get(compositionId);
326 var acDefinitionElement = acDefinition != null ? acDefinition.getElements().get(element.getDefinition()) : null;
328 return (acDefinitionElement != null) ? new CompositionElementDto(compositionId, element.getDefinition(),
329 acDefinitionElement.getAutomationCompositionElementToscaNodeTemplate().getProperties(),
330 acDefinitionElement.getOutProperties()) :
331 new CompositionElementDto(compositionId, element.getDefinition(),
332 Map.of(), Map.of(), ElementState.NOT_PRESENT);
336 * Get a Map of CompositionElementDto by elementId from the elements of an AutomationComposition.
338 * @param automationComposition the AutomationComposition
339 * @param compositionId the compositionId
340 * @return the Map of CompositionElementDto
342 public Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition,
343 UUID compositionId) {
344 var acDefinition = acElementsDefinitions.get(compositionId);
345 Map<UUID, CompositionElementDto> map = new HashMap<>();
346 for (var element : automationComposition.getElements().values()) {
347 var acDefinitionElement = (acDefinition != null) ? acDefinition.getElements().get(element.getDefinition()) :
349 var compositionElement = (acDefinitionElement != null)
350 ? new CompositionElementDto(compositionId, element.getDefinition(),
351 acDefinitionElement.getAutomationCompositionElementToscaNodeTemplate().getProperties(),
352 acDefinitionElement.getOutProperties()) :
353 new CompositionElementDto(compositionId, element.getDefinition(),
354 Map.of(), Map.of(), ElementState.NOT_PRESENT);
355 map.put(element.getId(), compositionElement);
360 public Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition) {
361 return getCompositionElementDtoMap(automationComposition, automationComposition.getCompositionId());
365 * Get a Map of InstanceElementDto by elementId from the elements of an AutomationComposition.
367 * @param automationComposition the AutomationComposition
368 * @return the Map of InstanceElementDto
370 public Map<UUID, InstanceElementDto> getInstanceElementDtoMap(AutomationComposition automationComposition) {
371 Map<UUID, InstanceElementDto> map = new HashMap<>();
372 for (var element : automationComposition.getElements().values()) {
373 var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(),
374 element.getProperties(), element.getOutProperties());
375 map.put(element.getId(), instanceElement);
381 * Create a new InstanceElementDto record with state New.
383 * @param instanceElement the InstanceElementDto
384 * @return a new InstanceElementDto
386 public static InstanceElementDto changeStateToNew(InstanceElementDto instanceElement) {
387 return new InstanceElementDto(instanceElement.instanceId(), instanceElement.elementId(),
388 instanceElement.inProperties(), instanceElement.outProperties(), ElementState.NEW);
392 * Create a new CompositionElementDto record with state New.
394 * @param compositionElement the CompositionElementDto
395 * @return a new CompositionElementDto
397 public static CompositionElementDto changeStateToNew(CompositionElementDto compositionElement) {
398 return new CompositionElementDto(compositionElement.compositionId(), compositionElement.elementDefinitionId(),
399 compositionElement.inProperties(), compositionElement.outProperties(), ElementState.NEW);
403 * Check composition is present and compare the last update.
405 * @param compositionId the instanceId
406 * @param revisionId the last Update
407 * @return true if the composition is updated
409 public boolean isCompositionDefinitionUpdated(UUID compositionId, UUID revisionId) {
410 if (revisionId == null) {
414 var acDefinition = acElementsDefinitions.get(compositionId);
415 if (acDefinition == null) {
418 return revisionId.equals(acDefinition.getRevisionId());
422 * Check instance is present and compare the last update.
424 * @param instanceId the instanceId
425 * @param revisionId the last Update
426 * @return true if the instance is updated
428 public boolean isInstanceUpdated(UUID instanceId, UUID revisionId) {
429 if (revisionId == null) {
433 var automationComposition = automationCompositions.get(instanceId);
434 if (automationComposition == null) {
437 return revisionId.equals(automationComposition.getRevisionId());