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
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;
23 import java.util.List;
25 import java.util.UUID;
26 import lombok.RequiredArgsConstructor;
27 import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher;
28 import org.onap.policy.clamp.models.acm.concepts.AcElementDeployAck;
29 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
30 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
31 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
32 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
33 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementInfo;
34 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionInfo;
35 import org.onap.policy.clamp.models.acm.concepts.DeployState;
36 import org.onap.policy.clamp.models.acm.concepts.LockState;
37 import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition;
38 import org.onap.policy.clamp.models.acm.concepts.ParticipantState;
39 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
40 import org.onap.policy.clamp.models.acm.concepts.SubState;
41 import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionDeployAck;
42 import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantMessageType;
43 import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantPrimeAck;
44 import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantStatus;
45 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48 import org.springframework.stereotype.Component;
51 @RequiredArgsConstructor
52 public class AutomationCompositionOutHandler {
53 private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionOutHandler.class);
55 private final ParticipantMessagePublisher publisher;
56 private final CacheProvider cacheProvider;
59 * Handle a automation composition element stage change message.
61 * @param instance the automationComposition Id
62 * @param elementId the automationComposition Element Id
63 * @param stage the next stage
64 * @param message the message
65 * @param stateChangeResult the indicator if error occurs
67 public void updateAutomationCompositionElementStage(UUID instance, UUID elementId,
68 StateChangeResult stateChangeResult, int stage, String message) {
70 if (instance == null || elementId == null) {
71 LOGGER.error("Cannot update Automation composition element stage, id is null");
75 var automationComposition = cacheProvider.getAutomationComposition(instance);
76 if (automationComposition == null) {
77 LOGGER.error("Cannot update Automation composition element stage, Automation composition id {} not present",
82 var element = automationComposition.getElements().get(elementId);
83 if (element == null) {
84 var msg = "Cannot update Automation composition element stage, AC Element id {} not present";
85 LOGGER.error(msg, elementId);
89 element.setRestarting(null);
91 var automationCompositionStateChangeAck =
92 new AutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
93 automationCompositionStateChangeAck.setParticipantId(cacheProvider.getParticipantId());
94 automationCompositionStateChangeAck.setMessage(message);
95 automationCompositionStateChangeAck.setResponseTo(cacheProvider.getMsgIdentification().get(element.getId()));
96 automationCompositionStateChangeAck.setStateChangeResult(stateChangeResult);
97 automationCompositionStateChangeAck.setStage(stage);
98 automationCompositionStateChangeAck.setAutomationCompositionId(instance);
99 automationCompositionStateChangeAck.getAutomationCompositionResultMap().put(element.getId(),
100 new AcElementDeployAck(element.getDeployState(), element.getLockState(), element.getOperationalState(),
101 element.getUseState(), element.getOutProperties(), true, message));
102 LOGGER.debug("Automation composition element {} stage changed to {}", elementId, stage);
103 automationCompositionStateChangeAck.setResult(true);
104 publisher.sendAutomationCompositionAck(automationCompositionStateChangeAck);
105 cacheProvider.getMsgIdentification().remove(element.getId());
109 * Handle a automation composition element state change message.
111 * @param instance the automationComposition Id
112 * @param elementId the automationComposition Element Id
113 * @param deployState the DeployState state
114 * @param lockState the LockState state
115 * @param message the message
116 * @param stateChangeResult the indicator if error occurs
118 public void updateAutomationCompositionElementState(UUID instance, UUID elementId,
119 DeployState deployState, LockState lockState, StateChangeResult stateChangeResult, String message) {
121 if (instance == null || elementId == null) {
122 LOGGER.error("Cannot update Automation composition element state, id is null");
126 var automationComposition = cacheProvider.getAutomationComposition(instance);
127 if (automationComposition == null) {
128 LOGGER.error("Cannot update Automation composition element state, Automation composition id {} not present",
133 var element = automationComposition.getElements().get(elementId);
134 if (element == null) {
135 var msg = "Cannot update Automation composition element state, AC Element id {} not present";
136 LOGGER.error(msg, elementId);
140 if ((element.getRestarting() == null)
141 && ((deployState != null && lockState != null) || (deployState == null && lockState == null))) {
142 LOGGER.error("state error {} and {} cannot be handled", deployState, lockState);
145 element.setRestarting(null);
147 if (deployState != null && !SubState.NONE.equals(element.getSubState())) {
148 handleSubState(automationComposition, element);
149 if (!StateChangeResult.NO_ERROR.equals(stateChangeResult)) {
150 stateChangeResult = StateChangeResult.NO_ERROR;
151 LOGGER.warn("SubState has always NO_ERROR result!");
153 } else if (deployState != null) {
154 handleDeployState(automationComposition, element, deployState);
156 if (lockState != null) {
157 handleLockState(automationComposition, element, lockState);
160 var automationCompositionStateChangeAck =
161 new AutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
162 automationCompositionStateChangeAck.setParticipantId(cacheProvider.getParticipantId());
163 automationCompositionStateChangeAck.setReplicaId(cacheProvider.getReplicaId());
164 automationCompositionStateChangeAck.setMessage(message);
165 automationCompositionStateChangeAck.setResponseTo(cacheProvider.getMsgIdentification().get(element.getId()));
166 automationCompositionStateChangeAck.setStateChangeResult(stateChangeResult);
167 automationCompositionStateChangeAck.setAutomationCompositionId(instance);
168 automationCompositionStateChangeAck.getAutomationCompositionResultMap().put(element.getId(),
169 new AcElementDeployAck(element.getDeployState(), element.getLockState(), element.getOperationalState(),
170 element.getUseState(), element.getOutProperties(), true, message));
171 LOGGER.debug("Automation composition element {} state changed to {}", elementId, deployState);
172 automationCompositionStateChangeAck.setResult(true);
173 publisher.sendAutomationCompositionAck(automationCompositionStateChangeAck);
174 cacheProvider.getMsgIdentification().remove(element.getId());
177 private void handleDeployState(AutomationComposition automationComposition, AutomationCompositionElement element,
178 DeployState deployState) {
179 element.setDeployState(deployState);
180 element.setLockState(DeployState.DEPLOYED.equals(element.getDeployState()) ? LockState.LOCKED : LockState.NONE);
181 var checkOpt = automationComposition.getElements().values().stream()
182 .filter(acElement -> !deployState.equals(acElement.getDeployState())).findAny();
183 if (checkOpt.isEmpty()) {
184 if (DeployState.DEPLOYED.equals(automationComposition.getDeployState())
185 && automationComposition.getCompositionTargetId() != null) {
186 // migration scenario
187 automationComposition.setCompositionId(automationComposition.getCompositionTargetId());
188 automationComposition.setCompositionTargetId(null);
190 automationComposition.setDeployState(deployState);
191 automationComposition.setLockState(element.getLockState());
192 automationComposition.setSubState(SubState.NONE);
194 if (DeployState.DELETED.equals(deployState)) {
195 cacheProvider.removeAutomationComposition(automationComposition.getInstanceId());
200 private void handleLockState(AutomationComposition automationComposition, AutomationCompositionElement element,
201 LockState lockState) {
202 element.setLockState(lockState);
203 var checkOpt = automationComposition.getElements().values().stream()
204 .filter(acElement -> !lockState.equals(acElement.getLockState())).findAny();
205 if (checkOpt.isEmpty()) {
206 automationComposition.setLockState(lockState);
207 automationComposition.setSubState(SubState.NONE);
211 private void handleSubState(AutomationComposition automationComposition, AutomationCompositionElement element) {
212 element.setSubState(SubState.NONE);
213 var checkOpt = automationComposition.getElements().values().stream()
214 .filter(acElement -> !SubState.NONE.equals(acElement.getSubState())).findAny();
215 if (checkOpt.isEmpty()) {
216 automationComposition.setSubState(SubState.NONE);
221 * Send Ac Element Info.
223 * @param automationCompositionId the automationComposition Id
224 * @param elementId the automationComposition Element id
225 * @param useState the use State
226 * @param operationalState the operational State
227 * @param outProperties the output Properties Map
229 public void sendAcElementInfo(UUID automationCompositionId, UUID elementId, String useState,
230 String operationalState, Map<String, Object> outProperties) {
232 if (automationCompositionId == null || elementId == null) {
233 LOGGER.error("Cannot update Automation composition element state, id is null");
237 var automationComposition = cacheProvider.getAutomationComposition(automationCompositionId);
238 if (automationComposition == null) {
239 LOGGER.error("Cannot update Automation composition element state, Automation composition id {} not present",
240 automationCompositionId);
244 var element = automationComposition.getElements().get(elementId);
245 if (element == null) {
246 var msg = "Cannot update Automation composition element state, AC Element id {} not present";
247 LOGGER.error(msg, elementId);
250 element.setOperationalState(operationalState);
251 element.setUseState(useState);
252 element.setOutProperties(outProperties);
254 var acInfo = new AutomationCompositionInfo();
255 acInfo.setAutomationCompositionId(automationCompositionId);
256 acInfo.setDeployState(automationComposition.getDeployState());
257 acInfo.setLockState(automationComposition.getLockState());
258 acInfo.setElements(List.of(getAutomationCompositionElementInfo(element)));
259 var statusMsg = createParticipantStatus();
260 statusMsg.setCompositionId(automationComposition.getCompositionId());
261 statusMsg.setAutomationCompositionInfoList(List.of(acInfo));
262 publisher.sendParticipantStatus(statusMsg);
266 * Get AutomationCompositionElementInfo from AutomationCompositionElement.
268 * @param element the AutomationCompositionElement
269 * @return the AutomationCompositionElementInfo
271 public AutomationCompositionElementInfo getAutomationCompositionElementInfo(AutomationCompositionElement element) {
272 var elementInfo = new AutomationCompositionElementInfo();
273 elementInfo.setAutomationCompositionElementId(element.getId());
274 elementInfo.setDeployState(element.getDeployState());
275 elementInfo.setLockState(element.getLockState());
276 elementInfo.setOperationalState(element.getOperationalState());
277 elementInfo.setUseState(element.getUseState());
278 elementInfo.setOutProperties(element.getOutProperties());
283 * Update Composition State for prime and deprime.
285 * @param compositionId the composition id
286 * @param state the Composition State
287 * @param stateChangeResult the indicator if error occurs
288 * @param message the message
290 public void updateCompositionState(UUID compositionId, AcTypeState state, StateChangeResult stateChangeResult,
292 var participantPrimeAck = new ParticipantPrimeAck();
293 participantPrimeAck.setCompositionId(compositionId);
294 participantPrimeAck.setMessage(message);
295 participantPrimeAck.setResult(true);
296 participantPrimeAck.setResponseTo(cacheProvider.getMsgIdentification().get(compositionId));
297 participantPrimeAck.setCompositionState(state);
298 participantPrimeAck.setStateChangeResult(stateChangeResult);
299 participantPrimeAck.setParticipantId(cacheProvider.getParticipantId());
300 participantPrimeAck.setReplicaId(cacheProvider.getReplicaId());
301 participantPrimeAck.setState(ParticipantState.ON_LINE);
302 publisher.sendParticipantPrimeAck(participantPrimeAck);
303 cacheProvider.getMsgIdentification().remove(compositionId);
304 if (AcTypeState.COMMISSIONED.equals(state) && StateChangeResult.NO_ERROR.equals(stateChangeResult)) {
305 cacheProvider.removeElementDefinition(compositionId);
310 * Send Composition Definition Info.
312 * @param compositionId the composition id
313 * @param elementId the Composition Definition Element id
314 * @param outProperties the output Properties Map
316 public void sendAcDefinitionInfo(UUID compositionId, ToscaConceptIdentifier elementId,
317 Map<String, Object> outProperties) {
318 if (compositionId == null) {
319 LOGGER.error("Cannot send Composition outProperties, id is null");
322 var statusMsg = createParticipantStatus();
323 statusMsg.setCompositionId(compositionId);
324 var acElementDefsMap = cacheProvider.getAcElementsDefinitions();
325 var acElementsDefinitions = acElementDefsMap.get(compositionId);
326 if (acElementsDefinitions == null) {
327 LOGGER.error("Cannot send Composition outProperties, id {} is null", compositionId);
330 var acElementDefinition = getAutomationCompositionElementDefinition(acElementsDefinitions, elementId);
331 if (acElementDefinition == null) {
332 LOGGER.error("Cannot send Composition outProperties, elementId {} not present", elementId);
335 acElementDefinition.setOutProperties(outProperties);
336 var participantDefinition = new ParticipantDefinition();
337 participantDefinition.setParticipantId(cacheProvider.getParticipantId());
338 participantDefinition.setAutomationCompositionElementDefinitionList(List.of(acElementDefinition));
339 statusMsg.setParticipantDefinitionUpdates(List.of(participantDefinition));
340 publisher.sendParticipantStatus(statusMsg);
343 private AutomationCompositionElementDefinition getAutomationCompositionElementDefinition(
344 Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> acElementsDefinition,
345 ToscaConceptIdentifier elementId) {
347 if (elementId == null) {
348 if (acElementsDefinition.size() == 1) {
349 return acElementsDefinition.values().iterator().next();
353 return acElementsDefinition.get(elementId);
356 private ParticipantStatus createParticipantStatus() {
357 var statusMsg = new ParticipantStatus();
358 statusMsg.setParticipantId(cacheProvider.getParticipantId());
359 statusMsg.setReplicaId(cacheProvider.getReplicaId());
360 statusMsg.setState(ParticipantState.ON_LINE);
361 statusMsg.setParticipantSupportedElementType(cacheProvider.getSupportedAcElementTypes());