3b982e0bcbf7d59dd04054e6f4df21d6d398d294
[policy/clamp.git] /
1 /*-
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
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.clamp.acm.participant.intermediary.handler.cache;
22
23 import java.util.HashMap;
24 import java.util.LinkedHashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.UUID;
28 import java.util.concurrent.ConcurrentHashMap;
29 import lombok.Getter;
30 import lombok.NonNull;
31 import lombok.Setter;
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;
50
51 @Component
52 public class CacheProvider {
53
54     @Getter
55     private final UUID participantId;
56
57     @Getter
58     @Setter
59     private boolean registered = false;
60
61     @Getter
62     private final UUID replicaId;
63
64     private final List<ParticipantSupportedElementType> supportedAcElementTypes;
65
66     @Getter
67     private final Map<UUID, AutomationComposition> automationCompositions = new ConcurrentHashMap<>();
68
69     @Getter
70     private final Map<UUID, AcDefinition> acElementsDefinitions = new ConcurrentHashMap<>();
71
72     @Getter
73     private final Map<UUID, UUID> msgIdentification = new ConcurrentHashMap<>();
74
75     @Getter
76     private final Map<UUID, AutomationCompositionMsg<?>> messagesOnHold = new HashMap<>();
77
78     /**
79      * Constructor.
80      *
81      * @param parameters the parameters of the participant
82      */
83     public CacheProvider(ParticipantParameters parameters) {
84         this.participantId = parameters.getIntermediaryParameters().getParticipantId();
85         this.supportedAcElementTypes = parameters.getIntermediaryParameters().getParticipantSupportedElementTypes();
86         this.replicaId = UUID.randomUUID();
87     }
88
89     public List<ParticipantSupportedElementType> getSupportedAcElementTypes() {
90         return PfUtils.mapList(supportedAcElementTypes, ParticipantSupportedElementType::new);
91     }
92
93     /**
94      * Get AutomationComposition by id.
95      *
96      * @param automationCompositionId the AutomationComposition Id
97      * @return the AutomationComposition
98      */
99     public AutomationComposition getAutomationComposition(@NonNull UUID automationCompositionId) {
100         return automationCompositions.get(automationCompositionId);
101     }
102
103     /**
104      * Remove AutomationComposition.
105      *
106      * @param automationCompositionId the AutomationComposition Id
107      */
108     public void removeAutomationComposition(@NonNull UUID automationCompositionId) {
109         automationCompositions.remove(automationCompositionId);
110     }
111
112     /**
113      * Add ElementDefinition.
114      *
115      * @param compositionId the composition Id
116      * @param list the list of AutomationCompositionElementDefinition to add
117      * @param revisionId the last Update
118      */
119     public void addElementDefinition(@NonNull UUID compositionId, List<AutomationCompositionElementDefinition> list,
120             UUID revisionId) {
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());
127             }
128             if (acElementDefinition.getAutomationCompositionElementToscaNodeTemplate().getProperties() == null) {
129                 acElementDefinition.getAutomationCompositionElementToscaNodeTemplate().setProperties(new HashMap<>());
130             }
131             acDefinition.getElements().put(acElementDefinition.getAcElementDefinitionId(), acElementDefinition);
132         }
133         acElementsDefinitions.put(compositionId, acDefinition);
134     }
135
136     public void removeElementDefinition(@NonNull UUID compositionId) {
137         acElementsDefinitions.remove(compositionId);
138     }
139
140     /**
141      * Get CommonProperties.
142      *
143      * @param instanceId the Automation Composition Id
144      * @param acElementId the Automation Composition Element Id
145      * @return the common Properties as Map
146      */
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());
151     }
152
153     /**
154      * Get CommonProperties.
155      *
156      * @param compositionId the composition Id
157      * @param definition the AutomationCompositionElementDefinition Id
158      * @return the common Properties as Map
159      */
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<>();
165         }
166         var map = acDefinition.getElements().get(definition);
167         return map != null ? map.getAutomationCompositionElementToscaNodeTemplate().getProperties() : new HashMap<>();
168     }
169
170     /**
171      * Initialize an AutomationComposition from a ParticipantDeploy.
172      *
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
177      */
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);
182     }
183
184     /**
185      * Initialize an AutomationComposition from a ParticipantDeploy.
186      *
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
193      */
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());
208             }
209             acElementMap.put(element.getId(), acElement);
210         }
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);
219     }
220
221     /**
222      * Initialize an AutomationComposition from a ParticipantRestartAc.
223      *
224      * @param compositionId the composition Id
225      * @param participantRestartAc the ParticipantRestartAc
226      */
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())) {
232                 continue;
233             }
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);
246         }
247
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);
257     }
258
259     /**
260      * Create AutomationCompositionElement to save in memory.
261      *
262      * @param element AcElementDeploy
263      * @return a new AutomationCompositionElement
264      */
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);
272         return acElement;
273     }
274
275     /**
276      * Create CompositionElementDto.
277      *
278      * @param compositionId the composition Id
279      * @param element AutomationComposition Element
280      * @return the CompositionElementDto
281      */
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;
285
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);
291     }
292
293     /**
294      * Get a Map of CompositionElementDto by elementId from the elements of an AutomationComposition.
295      *
296      * @param automationComposition the AutomationComposition
297      * @param compositionId the compositionId
298      * @return the Map of CompositionElementDto
299      */
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);
313         }
314         return map;
315     }
316
317     public Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition) {
318         return getCompositionElementDtoMap(automationComposition, automationComposition.getCompositionId());
319     }
320
321     /**
322      * Get a Map of InstanceElementDto by elementId from the elements of an AutomationComposition.
323      *
324      * @param automationComposition the AutomationComposition
325      * @return the Map of InstanceElementDto
326      */
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);
333         }
334         return map;
335     }
336
337     /**
338      * Create a new InstanceElementDto record with state New.
339      *
340      * @param instanceElement the InstanceElementDto
341      * @return a new InstanceElementDto
342      */
343     public static InstanceElementDto changeStateToNew(InstanceElementDto instanceElement) {
344         return new InstanceElementDto(instanceElement.instanceId(), instanceElement.elementId(),
345                 instanceElement.inProperties(), instanceElement.outProperties(), ElementState.NEW);
346     }
347
348     /**
349      * Create a new CompositionElementDto record with state New.
350      *
351      * @param compositionElement the CompositionElementDto
352      * @return a new CompositionElementDto
353      */
354     public static CompositionElementDto changeStateToNew(CompositionElementDto compositionElement) {
355         return new CompositionElementDto(compositionElement.compositionId(), compositionElement.elementDefinitionId(),
356                 compositionElement.inProperties(), compositionElement.outProperties(), ElementState.NEW);
357     }
358
359     /**
360      * Check composition is present and compare the last update.
361      *
362      * @param compositionId the instanceId
363      * @param revisionId the last Update
364      * @return true if the composition is updated
365      */
366     public boolean isCompositionDefinitionUpdated(UUID compositionId, UUID revisionId) {
367         if (revisionId == null) {
368             // old ACM-r
369             return true;
370         }
371         var acDefinition = acElementsDefinitions.get(compositionId);
372         if (acDefinition == null) {
373             return false;
374         }
375         return revisionId.equals(acDefinition.getRevisionId());
376     }
377
378     /**
379      * Check instance is present and compare the last update.
380      *
381      * @param instanceId the instanceId
382      * @param revisionId the last Update
383      * @return true if the instance is updated
384      */
385     public boolean isInstanceUpdated(UUID instanceId, UUID revisionId) {
386         if (revisionId == null) {
387             // old ACM-r
388             return true;
389         }
390         var automationComposition = automationCompositions.get(instanceId);
391         if (automationComposition == null) {
392             return false;
393         }
394         return revisionId.equals(automationComposition.getRevisionId());
395     }
396 }