2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2023 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.messages.dmaap.participant.AutomationCompositionDeployAck;
41 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType;
42 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantPrimeAck;
43 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus;
44 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47 import org.springframework.stereotype.Component;
50 @RequiredArgsConstructor
51 public class AutomationCompositionOutHandler {
52 private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionOutHandler.class);
54 private final ParticipantMessagePublisher publisher;
55 private final CacheProvider cacheProvider;
58 * Handle a automation composition element state change message.
60 * @param automationCompositionId the automationComposition Id
61 * @param elementId the automationComposition Element Id
62 * @param deployState the DeployState state
63 * @param lockState the LockState state
64 * @param message the message
65 * @param stateChangeResult the indicator if error occurs
67 public void updateAutomationCompositionElementState(UUID automationCompositionId, UUID elementId,
68 DeployState deployState, LockState lockState, StateChangeResult stateChangeResult, String message) {
70 if (automationCompositionId == null || elementId == null) {
71 LOGGER.error("Cannot update Automation composition element state, id is null");
75 var automationComposition = cacheProvider.getAutomationComposition(automationCompositionId);
76 if (automationComposition == null) {
77 LOGGER.error("Cannot update Automation composition element state, Automation composition id {} not present",
78 automationCompositionId);
82 var element = automationComposition.getElements().get(elementId);
83 if (element == null) {
84 var msg = "Cannot update Automation composition element state, AC Element id {} not present";
85 LOGGER.error(msg, elementId);
89 if ((element.getRestarting() == null)
90 && ((deployState != null && lockState != null) || (deployState == null && lockState == null))) {
91 LOGGER.error("state error {} and {} cannot be handled", deployState, lockState);
94 element.setRestarting(null);
96 if (deployState != null) {
97 handleDeployState(automationComposition, element, deployState);
99 if (lockState != null) {
100 handleLockState(automationComposition, element, lockState);
103 var automationCompositionStateChangeAck =
104 new AutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
105 automationCompositionStateChangeAck.setParticipantId(cacheProvider.getParticipantId());
106 automationCompositionStateChangeAck.setMessage(message);
107 automationCompositionStateChangeAck.setResponseTo(cacheProvider.getMsgIdentification().get(element.getId()));
108 automationCompositionStateChangeAck.setStateChangeResult(stateChangeResult);
109 automationCompositionStateChangeAck.setAutomationCompositionId(automationCompositionId);
110 automationCompositionStateChangeAck.getAutomationCompositionResultMap().put(element.getId(),
111 new AcElementDeployAck(element.getDeployState(), element.getLockState(), element.getOperationalState(),
112 element.getUseState(), element.getOutProperties(), true, message));
113 LOGGER.debug("Automation composition element {} state changed to {}", elementId, deployState);
114 automationCompositionStateChangeAck.setResult(true);
115 publisher.sendAutomationCompositionAck(automationCompositionStateChangeAck);
116 cacheProvider.getMsgIdentification().remove(element.getId());
119 private void handleDeployState(AutomationComposition automationComposition, AutomationCompositionElement element,
120 DeployState deployState) {
121 element.setDeployState(deployState);
122 element.setLockState(DeployState.DEPLOYED.equals(element.getDeployState()) ? LockState.LOCKED : LockState.NONE);
123 var checkOpt = automationComposition.getElements().values().stream()
124 .filter(acElement -> !deployState.equals(acElement.getDeployState())).findAny();
125 if (checkOpt.isEmpty()) {
126 if (DeployState.MIGRATING.equals(automationComposition.getDeployState())) {
127 // migration scenario
128 automationComposition.setCompositionId(automationComposition.getCompositionTargetId());
129 automationComposition.setCompositionTargetId(null);
131 automationComposition.setDeployState(deployState);
132 automationComposition.setLockState(element.getLockState());
134 if (DeployState.DELETED.equals(deployState)) {
135 cacheProvider.removeAutomationComposition(automationComposition.getInstanceId());
140 private void handleLockState(AutomationComposition automationComposition, AutomationCompositionElement element,
141 LockState lockState) {
142 element.setLockState(lockState);
143 var checkOpt = automationComposition.getElements().values().stream()
144 .filter(acElement -> !lockState.equals(acElement.getLockState())).findAny();
145 if (checkOpt.isEmpty()) {
146 automationComposition.setLockState(lockState);
151 * Send Ac Element Info.
153 * @param automationCompositionId the automationComposition Id
154 * @param elementId the automationComposition Element id
155 * @param useState the use State
156 * @param operationalState the operational State
157 * @param outProperties the output Properties Map
159 public void sendAcElementInfo(UUID automationCompositionId, UUID elementId, String useState,
160 String operationalState, Map<String, Object> outProperties) {
162 if (automationCompositionId == null || elementId == null) {
163 LOGGER.error("Cannot update Automation composition element state, id is null");
167 var automationComposition = cacheProvider.getAutomationComposition(automationCompositionId);
168 if (automationComposition == null) {
169 LOGGER.error("Cannot update Automation composition element state, Automation composition id {} not present",
170 automationCompositionId);
174 var element = automationComposition.getElements().get(elementId);
175 if (element == null) {
176 var msg = "Cannot update Automation composition element state, AC Element id {} not present";
177 LOGGER.error(msg, elementId);
180 element.setOperationalState(operationalState);
181 element.setUseState(useState);
182 element.setOutProperties(outProperties);
184 var acInfo = new AutomationCompositionInfo();
185 acInfo.setAutomationCompositionId(automationCompositionId);
186 acInfo.setDeployState(automationComposition.getDeployState());
187 acInfo.setLockState(automationComposition.getLockState());
188 acInfo.setElements(List.of(getAutomationCompositionElementInfo(element)));
189 var statusMsg = createParticipantStatus();
190 statusMsg.setCompositionId(automationComposition.getCompositionId());
191 statusMsg.setAutomationCompositionInfoList(List.of(acInfo));
192 publisher.sendParticipantStatus(statusMsg);
196 * Get AutomationCompositionElementInfo from AutomationCompositionElement.
198 * @param element the AutomationCompositionElement
199 * @return the AutomationCompositionElementInfo
201 public AutomationCompositionElementInfo getAutomationCompositionElementInfo(AutomationCompositionElement element) {
202 var elementInfo = new AutomationCompositionElementInfo();
203 elementInfo.setAutomationCompositionElementId(element.getId());
204 elementInfo.setDeployState(element.getDeployState());
205 elementInfo.setLockState(element.getLockState());
206 elementInfo.setOperationalState(element.getOperationalState());
207 elementInfo.setUseState(element.getUseState());
208 elementInfo.setOutProperties(element.getOutProperties());
213 * Update Composition State for prime and deprime.
215 * @param compositionId the composition id
216 * @param state the Composition State
217 * @param stateChangeResult the indicator if error occurs
218 * @param message the message
220 public void updateCompositionState(UUID compositionId, AcTypeState state, StateChangeResult stateChangeResult,
222 var participantPrimeAck = new ParticipantPrimeAck();
223 participantPrimeAck.setCompositionId(compositionId);
224 participantPrimeAck.setMessage(message);
225 participantPrimeAck.setResult(true);
226 participantPrimeAck.setResponseTo(cacheProvider.getMsgIdentification().get(compositionId));
227 participantPrimeAck.setCompositionState(state);
228 participantPrimeAck.setStateChangeResult(stateChangeResult);
229 participantPrimeAck.setParticipantId(cacheProvider.getParticipantId());
230 participantPrimeAck.setState(ParticipantState.ON_LINE);
231 publisher.sendParticipantPrimeAck(participantPrimeAck);
232 cacheProvider.getMsgIdentification().remove(compositionId);
233 if (AcTypeState.COMMISSIONED.equals(state) && StateChangeResult.NO_ERROR.equals(stateChangeResult)) {
234 cacheProvider.removeElementDefinition(compositionId);
239 * Send Composition Definition Info.
241 * @param compositionId the composition id
242 * @param elementId the Composition Definition Element id
243 * @param outProperties the output Properties Map
245 public void sendAcDefinitionInfo(UUID compositionId, ToscaConceptIdentifier elementId,
246 Map<String, Object> outProperties) {
247 if (compositionId == null) {
248 LOGGER.error("Cannot send Composition outProperties, id is null");
251 var statusMsg = createParticipantStatus();
252 statusMsg.setCompositionId(compositionId);
253 var acElementDefsMap = cacheProvider.getAcElementsDefinitions();
254 var acElementsDefinitions = acElementDefsMap.get(compositionId);
255 if (acElementsDefinitions == null) {
256 LOGGER.error("Cannot send Composition outProperties, id {} is null", compositionId);
259 var acElementDefinition = getAutomationCompositionElementDefinition(acElementsDefinitions, elementId);
260 if (acElementDefinition == null) {
261 LOGGER.error("Cannot send Composition outProperties, elementId {} not present", elementId);
264 acElementDefinition.setOutProperties(outProperties);
265 var participantDefinition = new ParticipantDefinition();
266 participantDefinition.setParticipantId(cacheProvider.getParticipantId());
267 participantDefinition.setAutomationCompositionElementDefinitionList(List.of(acElementDefinition));
268 statusMsg.setParticipantDefinitionUpdates(List.of(participantDefinition));
269 publisher.sendHeartbeat(statusMsg);
272 private AutomationCompositionElementDefinition getAutomationCompositionElementDefinition(
273 Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> acElementsDefinition,
274 ToscaConceptIdentifier elementId) {
276 if (elementId == null) {
277 if (acElementsDefinition.size() == 1) {
278 return acElementsDefinition.values().iterator().next();
282 return acElementsDefinition.get(elementId);
285 private ParticipantStatus createParticipantStatus() {
286 var statusMsg = new ParticipantStatus();
287 statusMsg.setParticipantId(cacheProvider.getParticipantId());
288 statusMsg.setState(ParticipantState.ON_LINE);
289 statusMsg.setParticipantSupportedElementType(cacheProvider.getSupportedAcElementTypes());