2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2021-2023 Nordix Foundation.
4 * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.clamp.acm.participant.intermediary.handler;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.UUID;
27 import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher;
28 import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
29 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
30 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
31 import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy;
32 import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils;
33 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
34 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionDeploy;
35 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionDeployAck;
36 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionStateChange;
37 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType;
38 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.PropertiesUpdate;
39 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
40 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder;
41 import org.onap.policy.clamp.models.acm.persistence.provider.AcInstanceStateResolver;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44 import org.springframework.stereotype.Component;
47 * This class is responsible for managing the state of all automation compositions in the participant.
50 public class AutomationCompositionHandler {
51 private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionHandler.class);
53 private final CacheProvider cacheProvider;
54 private final ParticipantMessagePublisher publisher;
55 private final ThreadHandler listener;
56 private final AcInstanceStateResolver acInstanceStateResolver;
59 * Constructor, set the participant ID and messageSender.
61 * @param cacheProvider the Cache Provider
62 * @param publisher the ParticipantMessage Publisher
63 * @param listener the ThreadHandler Listener
65 public AutomationCompositionHandler(CacheProvider cacheProvider, ParticipantMessagePublisher publisher,
66 ThreadHandler listener) {
67 this.cacheProvider = cacheProvider;
68 this.publisher = publisher;
69 this.listener = listener;
70 this.acInstanceStateResolver = new AcInstanceStateResolver();
74 * Handle a automation composition state change message.
76 * @param stateChangeMsg the state change message
78 public void handleAutomationCompositionStateChange(AutomationCompositionStateChange stateChangeMsg) {
79 if (stateChangeMsg.getAutomationCompositionId() == null) {
83 var automationComposition = cacheProvider.getAutomationComposition(stateChangeMsg.getAutomationCompositionId());
85 if (automationComposition == null) {
86 if (DeployOrder.DELETE.equals(stateChangeMsg.getDeployOrderedState())) {
87 var automationCompositionAck = new AutomationCompositionDeployAck(
88 ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
89 automationCompositionAck.setParticipantId(cacheProvider.getParticipantId());
90 automationCompositionAck.setMessage("Already deleted or never used");
91 automationCompositionAck.setResult(true);
92 automationCompositionAck.setStateChangeResult(StateChangeResult.NO_ERROR);
93 automationCompositionAck.setResponseTo(stateChangeMsg.getMessageId());
94 automationCompositionAck.setAutomationCompositionId(stateChangeMsg.getAutomationCompositionId());
95 publisher.sendAutomationCompositionAck(automationCompositionAck);
97 LOGGER.debug("Automation composition {} does not use this participant",
98 stateChangeMsg.getAutomationCompositionId());
103 if (!checkConsistantOrderState(automationComposition, stateChangeMsg.getDeployOrderedState(),
104 stateChangeMsg.getLockOrderedState())) {
105 LOGGER.warn("Not Consistant OrderState Automation composition {}",
106 stateChangeMsg.getAutomationCompositionId());
110 if (DeployOrder.NONE.equals(stateChangeMsg.getDeployOrderedState())) {
111 handleLockOrderState(stateChangeMsg.getMessageId(), automationComposition,
112 stateChangeMsg.getLockOrderedState(), stateChangeMsg.getStartPhase());
114 handleDeployOrderState(stateChangeMsg.getMessageId(), automationComposition,
115 stateChangeMsg.getDeployOrderedState(), stateChangeMsg.getStartPhase());
119 private boolean checkConsistantOrderState(AutomationComposition automationComposition, DeployOrder deployOrder,
120 LockOrder lockOrder) {
121 if (DeployOrder.UPDATE.equals(deployOrder)) {
124 return acInstanceStateResolver.resolve(deployOrder, lockOrder, automationComposition.getDeployState(),
125 automationComposition.getLockState(), automationComposition.getStateChangeResult()) != null;
129 * Method to handle state changes.
131 * @param messageId the messageId
132 * @param automationComposition participant response
133 * @param orderedState automation composition ordered state
134 * @param startPhaseMsg startPhase from message
136 private void handleDeployOrderState(UUID messageId, final AutomationComposition automationComposition,
137 DeployOrder orderedState, Integer startPhaseMsg) {
139 switch (orderedState) {
141 handleUndeployState(messageId, automationComposition, startPhaseMsg);
144 handleDeleteState(messageId, automationComposition, startPhaseMsg);
148 LOGGER.error("StateChange message has no state, state is null {}", automationComposition.getKey());
154 * Method to handle state changes.
156 * @param messageId the messageId
157 * @param automationComposition participant response
158 * @param orderedState automation composition ordered state
159 * @param startPhaseMsg startPhase from message
161 private void handleLockOrderState(UUID messageId, final AutomationComposition automationComposition,
162 LockOrder orderedState, Integer startPhaseMsg) {
164 switch (orderedState) {
166 handleLockState(messageId, automationComposition, startPhaseMsg);
169 handleUnlockState(messageId, automationComposition, startPhaseMsg);
172 LOGGER.error("StateChange message has no state, state is null {}", automationComposition.getKey());
178 * Handle a automation composition properties update message.
180 * @param updateMsg the properties update message
182 public void handleAcPropertyUpdate(PropertiesUpdate updateMsg) {
184 if (updateMsg.getParticipantUpdatesList().isEmpty()) {
185 LOGGER.warn("No AutomationCompositionElement updates in message {}",
186 updateMsg.getAutomationCompositionId());
190 for (var participantDeploy : updateMsg.getParticipantUpdatesList()) {
191 if (cacheProvider.getParticipantId().equals(participantDeploy.getParticipantId())) {
193 updateExistingElementsOnThisParticipant(updateMsg.getAutomationCompositionId(), participantDeploy);
195 callParticipantUpdateProperty(updateMsg.getMessageId(), participantDeploy.getAcElementList(),
196 updateMsg.getAutomationCompositionId());
202 * Handle a automation composition Deploy message.
204 * @param deployMsg the Deploy message
206 public void handleAutomationCompositionDeploy(AutomationCompositionDeploy deployMsg) {
208 if (deployMsg.getParticipantUpdatesList().isEmpty()) {
209 LOGGER.warn("No AutomationCompositionElement deploy in message {}", deployMsg.getAutomationCompositionId());
213 for (var participantDeploy : deployMsg.getParticipantUpdatesList()) {
214 if (cacheProvider.getParticipantId().equals(participantDeploy.getParticipantId())) {
215 if (deployMsg.isFirstStartPhase()) {
216 cacheProvider.initializeAutomationComposition(deployMsg.getCompositionId(),
217 deployMsg.getAutomationCompositionId(), participantDeploy);
219 callParticipanDeploy(deployMsg.getMessageId(), participantDeploy.getAcElementList(),
220 deployMsg.getStartPhase(), deployMsg.getAutomationCompositionId());
225 private void callParticipanDeploy(UUID messageId, List<AcElementDeploy> acElements, Integer startPhaseMsg,
227 for (var element : acElements) {
228 var commonProperties = cacheProvider.getCommonProperties(instanceId, element.getId());
229 int startPhase = ParticipantUtils.findStartPhase(commonProperties);
230 if (startPhaseMsg.equals(startPhase)) {
231 var map = new HashMap<>(commonProperties);
232 map.putAll(element.getProperties());
233 listener.deploy(messageId, instanceId, element, map);
238 private void callParticipantUpdateProperty(UUID messageId, List<AcElementDeploy> acElements, UUID instanceId) {
239 for (var element : acElements) {
240 listener.update(messageId, instanceId, element, element.getProperties());
244 private void updateExistingElementsOnThisParticipant(UUID instanceId, ParticipantDeploy participantDeploy) {
245 var acElementList = cacheProvider.getAutomationComposition(instanceId).getElements();
246 for (var element : participantDeploy.getAcElementList()) {
247 var acElement = acElementList.get(element.getId());
248 acElement.getProperties().putAll(element.getProperties());
253 * Method to handle when the new state from participant is UNINITIALISED state.
255 * @param messageId the messageId
256 * @param automationComposition participant response
257 * @param startPhaseMsg startPhase from message
259 private void handleUndeployState(UUID messageId, final AutomationComposition automationComposition,
260 Integer startPhaseMsg) {
261 for (var acElement : automationComposition.getElements().values()) {
262 int startPhase = ParticipantUtils.findStartPhase(
263 cacheProvider.getCommonProperties(automationComposition.getInstanceId(), acElement.getId()));
264 if (startPhaseMsg.equals(startPhase)) {
265 listener.undeploy(messageId, automationComposition.getInstanceId(), acElement.getId());
270 private void handleDeleteState(UUID messageId, final AutomationComposition automationComposition,
271 Integer startPhaseMsg) {
272 for (var acElement : automationComposition.getElements().values()) {
273 int startPhase = ParticipantUtils.findStartPhase(
274 cacheProvider.getCommonProperties(automationComposition.getInstanceId(), acElement.getId()));
275 if (startPhaseMsg.equals(startPhase)) {
276 listener.delete(messageId, automationComposition.getInstanceId(), acElement.getId());
282 * Method to handle when the new state from participant is PASSIVE state.
284 * @param messageId the messageId
285 * @param automationComposition participant response
286 * @param startPhaseMsg startPhase from message
288 private void handleLockState(UUID messageId, final AutomationComposition automationComposition,
289 Integer startPhaseMsg) {
290 for (var acElement : automationComposition.getElements().values()) {
291 int startPhase = ParticipantUtils.findStartPhase(
292 cacheProvider.getCommonProperties(automationComposition.getInstanceId(), acElement.getId()));
293 if (startPhaseMsg.equals(startPhase)) {
294 listener.lock(messageId, automationComposition.getInstanceId(), acElement.getId());
300 * Method to handle when the new state from participant is RUNNING state.
302 * @param messageId the messageId
303 * @param automationComposition participant response
304 * @param startPhaseMsg startPhase from message
306 private void handleUnlockState(UUID messageId, final AutomationComposition automationComposition,
307 Integer startPhaseMsg) {
308 for (var acElement : automationComposition.getElements().values()) {
309 int startPhase = ParticipantUtils.findStartPhase(
310 cacheProvider.getCommonProperties(automationComposition.getInstanceId(), acElement.getId()));
311 if (startPhaseMsg.equals(startPhase)) {
312 listener.unlock(messageId, automationComposition.getInstanceId(), acElement.getId());
318 * Handles prime a Composition Definition.
320 * @param messageId the messageId
321 * @param compositionId the compositionId
322 * @param list the list of AutomationCompositionElementDefinition
324 public void prime(UUID messageId, UUID compositionId, List<AutomationCompositionElementDefinition> list) {
325 listener.prime(messageId, compositionId, list);
329 * Handles deprime a Composition Definition.
331 * @param messageId the messageId
332 * @param compositionId the compositionId
334 public void deprime(UUID messageId, UUID compositionId) {
335 listener.deprime(messageId, compositionId);