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 acDefinition = acElementsDefinitions.get(compositionId);
163 if (acDefinition == null) {
164 return new HashMap<>();
166 var map = acDefinition.getElements().get(definition);
167 return map != null ? map.getAutomationCompositionElementToscaNodeTemplate().getProperties() : new HashMap<>();
171 * Initialize an AutomationComposition from a ParticipantDeploy.
173 * @param compositionId the composition Id
174 * @param instanceId the Automation Composition Id
175 * @param participantDeploy the ParticipantDeploy
176 * @param revisionId the identification of the last update
178 public void initializeAutomationComposition(@NonNull UUID compositionId, @NonNull UUID instanceId,
179 ParticipantDeploy participantDeploy, UUID revisionId) {
180 initializeAutomationComposition(compositionId, instanceId, participantDeploy,
181 DeployState.DEPLOYING, SubState.NONE, revisionId);
185 * Initialize an AutomationComposition from a ParticipantDeploy.
187 * @param compositionId the composition Id
188 * @param instanceId the Automation Composition Id
189 * @param participantDeploy the ParticipantDeploy
190 * @param deployState the DeployState
191 * @param subState the SubState
192 * @param revisionId the identification of the last update
194 public void initializeAutomationComposition(@NonNull UUID compositionId, @NonNull UUID instanceId,
195 ParticipantDeploy participantDeploy, DeployState deployState, SubState subState, UUID revisionId) {
196 var acLast = automationCompositions.get(instanceId);
197 Map<UUID, AutomationCompositionElement> acElementMap = new LinkedHashMap<>();
198 for (var element : participantDeploy.getAcElementList()) {
199 var acElement = createAutomationCompositionElement(element);
200 acElement.setParticipantId(getParticipantId());
201 acElement.setDeployState(deployState);
202 acElement.setSubState(subState);
203 var acElementLast = acLast != null ? acLast.getElements().get(element.getId()) : null;
204 if (acElementLast != null) {
205 acElement.setOutProperties(acElementLast.getOutProperties());
206 acElement.setOperationalState(acElementLast.getOperationalState());
207 acElement.setUseState(acElementLast.getUseState());
209 acElementMap.put(element.getId(), acElement);
211 var automationComposition = new AutomationComposition();
212 automationComposition.setCompositionId(compositionId);
213 automationComposition.setInstanceId(instanceId);
214 automationComposition.setElements(acElementMap);
215 automationComposition.setDeployState(deployState);
216 automationComposition.setSubState(subState);
217 automationComposition.setRevisionId(revisionId);
218 automationCompositions.put(instanceId, automationComposition);
222 * Initialize an AutomationComposition from a ParticipantRestartAc.
224 * @param compositionId the composition Id
225 * @param participantRestartAc the ParticipantRestartAc
227 public void initializeAutomationComposition(@NonNull UUID compositionId,
228 ParticipantRestartAc participantRestartAc) {
229 Map<UUID, AutomationCompositionElement> acElementMap = new LinkedHashMap<>();
230 for (var element : participantRestartAc.getAcElementList()) {
231 if (!getParticipantId().equals(element.getParticipantId())) {
234 var acElement = new AutomationCompositionElement();
235 acElement.setId(element.getId());
236 acElement.setParticipantId(getParticipantId());
237 acElement.setDefinition(element.getDefinition());
238 acElement.setDeployState(element.getDeployState());
239 acElement.setLockState(element.getLockState());
240 acElement.setSubState(SubState.NONE);
241 acElement.setOperationalState(element.getOperationalState());
242 acElement.setUseState(element.getUseState());
243 acElement.setProperties(element.getProperties());
244 acElement.setOutProperties(element.getOutProperties());
245 acElementMap.put(element.getId(), acElement);
248 var automationComposition = new AutomationComposition();
249 automationComposition.setCompositionId(compositionId);
250 automationComposition.setDeployState(participantRestartAc.getDeployState());
251 automationComposition.setLockState(participantRestartAc.getLockState());
252 automationComposition.setInstanceId(participantRestartAc.getAutomationCompositionId());
253 automationComposition.setElements(acElementMap);
254 automationComposition.setStateChangeResult(participantRestartAc.getStateChangeResult());
255 automationComposition.setRevisionId(participantRestartAc.getRevisionId());
256 automationCompositions.put(automationComposition.getInstanceId(), automationComposition);
260 * Create AutomationCompositionElement to save in memory.
262 * @param element AcElementDeploy
263 * @return a new AutomationCompositionElement
265 public static AutomationCompositionElement createAutomationCompositionElement(AcElementDeploy element) {
266 var acElement = new AutomationCompositionElement();
267 acElement.setId(element.getId());
268 acElement.setDefinition(element.getDefinition());
269 acElement.setProperties(element.getProperties());
270 acElement.setSubState(SubState.NONE);
271 acElement.setLockState(LockState.LOCKED);
276 * Create CompositionElementDto.
278 * @param compositionId the composition Id
279 * @param element AutomationComposition Element
280 * @return the CompositionElementDto
282 public CompositionElementDto createCompositionElementDto(UUID compositionId, AutomationCompositionElement element) {
283 var acDefinition = acElementsDefinitions.get(compositionId);
284 var acDefinitionElement = acDefinition != null ? acDefinition.getElements().get(element.getDefinition()) : null;
286 return (acDefinitionElement != null) ? new CompositionElementDto(compositionId, element.getDefinition(),
287 acDefinitionElement.getAutomationCompositionElementToscaNodeTemplate().getProperties(),
288 acDefinitionElement.getOutProperties()) :
289 new CompositionElementDto(compositionId, element.getDefinition(),
290 Map.of(), Map.of(), ElementState.NOT_PRESENT);
294 * Get a Map of CompositionElementDto by elementId from the elements of an AutomationComposition.
296 * @param automationComposition the AutomationComposition
297 * @param compositionId the compositionId
298 * @return the Map of CompositionElementDto
300 public Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition,
301 UUID compositionId) {
302 var acDefinition = acElementsDefinitions.get(compositionId);
303 Map<UUID, CompositionElementDto> map = new HashMap<>();
304 for (var element : automationComposition.getElements().values()) {
305 var acDefinitionElement = acDefinition.getElements().get(element.getDefinition());
306 var compositionElement = (acDefinitionElement != null)
307 ? new CompositionElementDto(compositionId, element.getDefinition(),
308 acDefinitionElement.getAutomationCompositionElementToscaNodeTemplate().getProperties(),
309 acDefinitionElement.getOutProperties()) :
310 new CompositionElementDto(compositionId, element.getDefinition(),
311 Map.of(), Map.of(), ElementState.NOT_PRESENT);
312 map.put(element.getId(), compositionElement);
317 public Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition) {
318 return getCompositionElementDtoMap(automationComposition, automationComposition.getCompositionId());
322 * Get a Map of InstanceElementDto by elementId from the elements of an AutomationComposition.
324 * @param automationComposition the AutomationComposition
325 * @return the Map of InstanceElementDto
327 public Map<UUID, InstanceElementDto> getInstanceElementDtoMap(AutomationComposition automationComposition) {
328 Map<UUID, InstanceElementDto> map = new HashMap<>();
329 for (var element : automationComposition.getElements().values()) {
330 var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(),
331 element.getProperties(), element.getOutProperties());
332 map.put(element.getId(), instanceElement);
338 * Create a new InstanceElementDto record with state New.
340 * @param instanceElement the InstanceElementDto
341 * @return a new InstanceElementDto
343 public static InstanceElementDto changeStateToNew(InstanceElementDto instanceElement) {
344 return new InstanceElementDto(instanceElement.instanceId(), instanceElement.elementId(),
345 instanceElement.inProperties(), instanceElement.outProperties(), ElementState.NEW);
349 * Create a new CompositionElementDto record with state New.
351 * @param compositionElement the CompositionElementDto
352 * @return a new CompositionElementDto
354 public static CompositionElementDto changeStateToNew(CompositionElementDto compositionElement) {
355 return new CompositionElementDto(compositionElement.compositionId(), compositionElement.elementDefinitionId(),
356 compositionElement.inProperties(), compositionElement.outProperties(), ElementState.NEW);
360 * Check composition is present and compare the last update.
362 * @param compositionId the instanceId
363 * @param revisionId the last Update
364 * @return true if the composition is updated
366 public boolean isCompositionDefinitionUpdated(UUID compositionId, UUID revisionId) {
367 if (revisionId == null) {
371 var acDefinition = acElementsDefinitions.get(compositionId);
372 if (acDefinition == null) {
375 return revisionId.equals(acDefinition.getRevisionId());
379 * Check instance is present and compare the last update.
381 * @param instanceId the instanceId
382 * @param revisionId the last Update
383 * @return true if the instance is updated
385 public boolean isInstanceUpdated(UUID instanceId, UUID revisionId) {
386 if (revisionId == null) {
390 var automationComposition = automationCompositions.get(instanceId);
391 if (automationComposition == null) {
394 return revisionId.equals(automationComposition.getRevisionId());