c6915026a2e6ab27c339968cd5442fc93d03b818
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2023-2024 Nordix Foundation.
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;
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.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
50 import org.springframework.stereotype.Component;
51
52 @Component
53 public class CacheProvider {
54
55     @Getter
56     private final UUID participantId;
57
58     @Getter
59     @Setter
60     private boolean registered = false;
61
62     @Getter
63     private final UUID replicaId;
64
65     private final List<ParticipantSupportedElementType> supportedAcElementTypes;
66
67     @Getter
68     private final Map<UUID, AutomationComposition> automationCompositions = new ConcurrentHashMap<>();
69
70     @Getter
71     private final Map<UUID, Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition>> acElementsDefinitions =
72             new ConcurrentHashMap<>();
73
74     @Getter
75     private final Map<UUID, UUID> msgIdentification = new ConcurrentHashMap<>();
76
77     @Getter
78     private final Map<UUID, ToscaServiceTemplate> serviceTemplateFragmentMap = new ConcurrentHashMap<>();
79
80     /**
81      * Constructor.
82      *
83      * @param parameters the parameters of the participant
84      */
85     public CacheProvider(ParticipantParameters parameters) {
86         this.participantId = parameters.getIntermediaryParameters().getParticipantId();
87         this.supportedAcElementTypes = parameters.getIntermediaryParameters().getParticipantSupportedElementTypes();
88         this.replicaId = UUID.randomUUID();
89     }
90
91     public List<ParticipantSupportedElementType> getSupportedAcElementTypes() {
92         return PfUtils.mapList(supportedAcElementTypes, ParticipantSupportedElementType::new);
93     }
94
95     /**
96      * Get AutomationComposition by id.
97      *
98      * @param automationCompositionId the AutomationComposition Id
99      * @return the AutomationComposition
100      */
101     public AutomationComposition getAutomationComposition(@NonNull UUID automationCompositionId) {
102         return automationCompositions.get(automationCompositionId);
103     }
104
105     /**
106      * Remove AutomationComposition.
107      *
108      * @param automationCompositionId the AutomationComposition Id
109      */
110     public void removeAutomationComposition(@NonNull UUID automationCompositionId) {
111         automationCompositions.remove(automationCompositionId);
112     }
113
114     /**
115      * Add ElementDefinition.
116      *
117      * @param compositionId the composition Id
118      * @param list the list of AutomationCompositionElementDefinition to add
119      */
120     public void addElementDefinition(@NonNull UUID compositionId, List<AutomationCompositionElementDefinition> list) {
121         Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> map = new HashMap<>();
122         for (var acElementDefinition : list) {
123             map.put(acElementDefinition.getAcElementDefinitionId(), acElementDefinition);
124         }
125         acElementsDefinitions.put(compositionId, map);
126     }
127
128     public void removeElementDefinition(@NonNull UUID compositionId) {
129         acElementsDefinitions.remove(compositionId);
130         serviceTemplateFragmentMap.remove(compositionId);
131     }
132
133     /**
134      * Get CommonProperties.
135      *
136      * @param instanceId the Automation Composition Id
137      * @param acElementId the Automation Composition Element Id
138      * @return the common Properties as Map
139      */
140     public Map<String, Object> getCommonProperties(@NonNull UUID instanceId, @NonNull UUID acElementId) {
141         var automationComposition = automationCompositions.get(instanceId);
142         var map = acElementsDefinitions.get(automationComposition.getCompositionId());
143         var element = automationComposition.getElements().get(acElementId);
144         return getAcElementDefinition(map, element.getDefinition())
145                 .getAutomationCompositionElementToscaNodeTemplate().getProperties();
146     }
147
148     /**
149      * Get CommonProperties.
150      *
151      * @param compositionId the composition Id
152      * @param definition the AutomationCompositionElementDefinition Id
153      * @return the common Properties as Map
154      */
155     public Map<String, Object> getCommonProperties(@NonNull UUID compositionId,
156         @NonNull ToscaConceptIdentifier definition) {
157         return getAcElementDefinition(acElementsDefinitions.get(compositionId), definition)
158                 .getAutomationCompositionElementToscaNodeTemplate().getProperties();
159     }
160
161     private AutomationCompositionElementDefinition getAcElementDefinition(
162             Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> map,
163             ToscaConceptIdentifier definition) {
164         var nodeTemplate = map.get(definition);
165         if (nodeTemplate == null) {
166             nodeTemplate = new AutomationCompositionElementDefinition();
167             nodeTemplate.setAutomationCompositionElementToscaNodeTemplate(new ToscaNodeTemplate());
168             nodeTemplate.getAutomationCompositionElementToscaNodeTemplate().setProperties(new HashMap<>());
169         }
170         return nodeTemplate;
171     }
172
173     /**
174      * Initialize an AutomationComposition from a ParticipantDeploy.
175      *
176      * @param compositionId the composition Id
177      * @param instanceId the Automation Composition Id
178      * @param participantDeploy the ParticipantDeploy
179      */
180     public void initializeAutomationComposition(@NonNull UUID compositionId, @NonNull UUID instanceId,
181             ParticipantDeploy participantDeploy) {
182         initializeAutomationComposition(compositionId, instanceId, participantDeploy,
183             DeployState.DEPLOYING, SubState.NONE);
184     }
185
186     /**
187      * Initialize an AutomationComposition from a ParticipantDeploy.
188      *
189      * @param compositionId the composition Id
190      * @param instanceId the Automation Composition Id
191      * @param participantDeploy the ParticipantDeploy
192      * @param deployState the DeployState
193      * @param subState the SubState
194      */
195     public void initializeAutomationComposition(@NonNull UUID compositionId, @NonNull UUID instanceId,
196             ParticipantDeploy participantDeploy, DeployState deployState, SubState subState) {
197         var acLast = automationCompositions.get(instanceId);
198         Map<UUID, AutomationCompositionElement> acElementMap = new LinkedHashMap<>();
199         for (var element : participantDeploy.getAcElementList()) {
200             var acElement = createAutomationCompositionElement(element);
201             acElement.setParticipantId(getParticipantId());
202             acElement.setDeployState(deployState);
203             acElement.setSubState(subState);
204             var acElementLast = acLast != null ? acLast.getElements().get(element.getId()) : null;
205             if (acElementLast != null) {
206                 acElement.setOutProperties(acElementLast.getOutProperties());
207                 acElement.setOperationalState(acElementLast.getOperationalState());
208                 acElement.setUseState(acElementLast.getUseState());
209                 if (element.getToscaServiceTemplateFragment() != null) {
210                     serviceTemplateFragmentMap.put(compositionId, element.getToscaServiceTemplateFragment());
211                 }
212             }
213             acElementMap.put(element.getId(), acElement);
214         }
215         var automationComposition = new AutomationComposition();
216         automationComposition.setCompositionId(compositionId);
217         automationComposition.setInstanceId(instanceId);
218         automationComposition.setElements(acElementMap);
219         automationComposition.setDeployState(deployState);
220         automationComposition.setSubState(subState);
221         automationCompositions.put(instanceId, automationComposition);
222     }
223
224     /**
225      * Initialize an AutomationComposition from a ParticipantRestartAc.
226      *
227      * @param compositionId the composition Id
228      * @param participantRestartAc the ParticipantRestartAc
229      */
230     public void initializeAutomationComposition(@NonNull UUID compositionId,
231             ParticipantRestartAc participantRestartAc) {
232         Map<UUID, AutomationCompositionElement> acElementMap = new LinkedHashMap<>();
233         for (var element : participantRestartAc.getAcElementList()) {
234             if (!getParticipantId().equals(element.getParticipantId())) {
235                 continue;
236             }
237             var acElement = new AutomationCompositionElement();
238             acElement.setId(element.getId());
239             acElement.setParticipantId(getParticipantId());
240             acElement.setDefinition(element.getDefinition());
241             acElement.setDeployState(element.getDeployState());
242             acElement.setLockState(element.getLockState());
243             acElement.setSubState(SubState.NONE);
244             acElement.setOperationalState(element.getOperationalState());
245             acElement.setUseState(element.getUseState());
246             acElement.setProperties(element.getProperties());
247             acElement.setOutProperties(element.getOutProperties());
248             acElementMap.put(element.getId(), acElement);
249             if (element.getToscaServiceTemplateFragment() != null) {
250                 serviceTemplateFragmentMap.put(compositionId, element.getToscaServiceTemplateFragment());
251             }
252         }
253
254         var automationComposition = new AutomationComposition();
255         automationComposition.setCompositionId(compositionId);
256         automationComposition.setDeployState(participantRestartAc.getDeployState());
257         automationComposition.setLockState(participantRestartAc.getLockState());
258         automationComposition.setInstanceId(participantRestartAc.getAutomationCompositionId());
259         automationComposition.setElements(acElementMap);
260         automationComposition.setStateChangeResult(participantRestartAc.getStateChangeResult());
261         automationCompositions.put(automationComposition.getInstanceId(), automationComposition);
262     }
263
264     /**
265      * Create AutomationCompositionElement to save in memory.
266      *
267      * @param element AcElementDeploy
268      * @return a new AutomationCompositionElement
269      */
270     public static AutomationCompositionElement createAutomationCompositionElement(AcElementDeploy element) {
271         var acElement = new AutomationCompositionElement();
272         acElement.setId(element.getId());
273         acElement.setDefinition(element.getDefinition());
274         acElement.setProperties(element.getProperties());
275         acElement.setSubState(SubState.NONE);
276         acElement.setLockState(LockState.LOCKED);
277         return acElement;
278     }
279
280     /**
281      * Create CompositionElementDto.
282      *
283      * @param compositionId the composition Id
284      * @param element AutomationComposition Element
285      * @param compositionInProperties composition definition InProperties
286      * @return the CompositionElementDto
287      */
288     public CompositionElementDto createCompositionElementDto(UUID compositionId, AutomationCompositionElement element,
289             Map<String, Object> compositionInProperties) {
290         var compositionOutProperties = getAcElementDefinition(acElementsDefinitions
291                 .get(compositionId), element.getDefinition()).getOutProperties();
292         return new CompositionElementDto(compositionId,
293                 element.getDefinition(), compositionInProperties, compositionOutProperties);
294     }
295
296     /**
297      * Get a Map of CompositionElementDto by elementId from the elements of an AutomationComposition.
298      *
299      * @param automationComposition the AutomationComposition
300      * @param compositionId the compositionId
301      * @return the Map of CompositionElementDto
302      */
303     public Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition,
304             UUID compositionId) {
305         var definitions = acElementsDefinitions.get(compositionId);
306         Map<UUID, CompositionElementDto> map = new HashMap<>();
307         for (var element : automationComposition.getElements().values()) {
308             var definition = definitions.get(element.getDefinition());
309             var compositionElement = (definition != null)
310                     ? new CompositionElementDto(compositionId, element.getDefinition(),
311                             definition.getAutomationCompositionElementToscaNodeTemplate().getProperties(),
312                             definition.getOutProperties()) :
313                     new CompositionElementDto(compositionId, element.getDefinition(),
314                             Map.of(), Map.of(), ElementState.NOT_PRESENT);
315             map.put(element.getId(), compositionElement);
316         }
317         return map;
318     }
319
320     public Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition) {
321         return getCompositionElementDtoMap(automationComposition, automationComposition.getCompositionId());
322     }
323
324     /**
325      * Get a Map of InstanceElementDto by elementId from the elements of an AutomationComposition.
326      *
327      * @param automationComposition the AutomationComposition
328      * @return the Map of InstanceElementDto
329      */
330     public Map<UUID, InstanceElementDto> getInstanceElementDtoMap(AutomationComposition automationComposition) {
331         Map<UUID, InstanceElementDto> map = new HashMap<>();
332         var serviceTemplateFragment = serviceTemplateFragmentMap.get(automationComposition.getCompositionId());
333         for (var element : automationComposition.getElements().values()) {
334             var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(),
335                     serviceTemplateFragment, element.getProperties(), element.getOutProperties());
336             map.put(element.getId(), instanceElement);
337         }
338         return map;
339     }
340
341     /**
342      * Create a new InstanceElementDto record with state New.
343      *
344      * @param instanceElement the InstanceElementDto
345      * @return a new InstanceElementDto
346      */
347     public static InstanceElementDto changeStateToNew(InstanceElementDto instanceElement) {
348         return new InstanceElementDto(instanceElement.instanceId(), instanceElement.elementId(),
349                 instanceElement.toscaServiceTemplateFragment(),
350                 instanceElement.inProperties(), instanceElement.outProperties(), ElementState.NEW);
351     }
352
353     /**
354      * Create a new CompositionElementDto record with state New.
355      *
356      * @param compositionElement the CompositionElementDto
357      * @return a new CompositionElementDto
358      */
359     public static CompositionElementDto changeStateToNew(CompositionElementDto compositionElement) {
360         return new CompositionElementDto(compositionElement.compositionId(), compositionElement.elementDefinitionId(),
361                 compositionElement.inProperties(), compositionElement.outProperties(), ElementState.NEW);
362     }
363 }