2 * ============LICENSE_START=======================================================
3 * Copyright (C) 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.api.CompositionElementDto;
28 import org.onap.policy.clamp.acm.participant.intermediary.api.ElementState;
29 import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto;
30 import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
31 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
32 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
33 import org.onap.policy.clamp.models.acm.concepts.DeployState;
34 import org.onap.policy.clamp.models.acm.concepts.SubState;
35 import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration;
36 import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionPrepare;
37 import org.onap.policy.clamp.models.acm.utils.AcmUtils;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40 import org.springframework.stereotype.Component;
43 @RequiredArgsConstructor
44 public class AcSubStateHandler {
46 private static final Logger LOGGER = LoggerFactory.getLogger(AcSubStateHandler.class);
48 private final CacheProvider cacheProvider;
49 private final ThreadHandler listener;
52 * Handles AutomationComposition Migration Precheck.
54 * @param migrationMsg the AutomationCompositionMigration
56 public void handleAcMigrationPrecheck(AutomationCompositionMigration migrationMsg) {
57 if (migrationMsg.getAutomationCompositionId() == null || migrationMsg.getCompositionTargetId() == null) {
61 var automationComposition = cacheProvider.getAutomationComposition(migrationMsg.getAutomationCompositionId());
62 if (automationComposition == null) {
63 LOGGER.debug("Automation composition {} does not use this participant",
64 migrationMsg.getAutomationCompositionId());
67 automationComposition.setSubState(SubState.MIGRATION_PRECHECKING);
68 for (var participantDeploy : migrationMsg.getParticipantUpdatesList()) {
69 if (cacheProvider.getParticipantId().equals(participantDeploy.getParticipantId())) {
71 callParticipantMigratePrecheck(migrationMsg.getMessageId(), participantDeploy.getAcElementList(),
72 automationComposition, migrationMsg.getCompositionTargetId());
77 private void callParticipantMigratePrecheck(UUID messageId, List<AcElementDeploy> acElements,
78 AutomationComposition automationComposition, UUID compositionTargetId) {
79 var compositionElementMap = cacheProvider.getCompositionElementDtoMap(automationComposition);
80 var instanceElementMap = cacheProvider.getInstanceElementDtoMap(automationComposition);
81 var acElementList = automationComposition.getElements();
82 for (var acElement : acElements) {
83 var element = acElementList.get(acElement.getId());
84 if (element != null) {
85 element.setSubState(SubState.MIGRATION_PRECHECKING);
88 var acCopyMigrateTo = new AutomationComposition(automationComposition);
89 var acElementCopyList = acCopyMigrateTo.getElements();
90 for (var acElement : acElements) {
91 var element = acElementCopyList.get(acElement.getId());
92 if (element != null) {
93 AcmUtils.recursiveMerge(element.getProperties(), acElement.getProperties());
94 element.setDefinition(acElement.getDefinition());
96 element = CacheProvider.createAutomationCompositionElement(acElement);
97 element.setSubState(SubState.MIGRATION_PRECHECKING);
98 acElementCopyList.put(element.getId(), element);
101 var toDelete = acElementCopyList.values().stream()
102 .filter(el -> !SubState.MIGRATION_PRECHECKING.equals(el.getSubState()))
103 .map(AutomationCompositionElement::getId)
105 toDelete.forEach(acElementCopyList::remove);
107 var compositionElementTargetMap = cacheProvider.getCompositionElementDtoMap(acCopyMigrateTo,
108 compositionTargetId);
109 var instanceElementMigrateMap = cacheProvider.getInstanceElementDtoMap(acCopyMigrateTo);
111 for (var acElement : acElements) {
112 var compositionElement = compositionElementMap.get(acElement.getId());
113 var compositionElementTarget = compositionElementTargetMap.get(acElement.getId());
114 var instanceElement = instanceElementMap.get(acElement.getId());
115 var instanceElementMigrate = instanceElementMigrateMap.get(acElement.getId());
117 if (instanceElement == null) {
118 // new element scenario
119 compositionElement = new CompositionElementDto(automationComposition.getCompositionId(),
120 acElement.getDefinition(), Map.of(), Map.of(), ElementState.NOT_PRESENT);
121 instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), acElement.getId(),
122 Map.of(), Map.of(), ElementState.NOT_PRESENT);
123 compositionElementTarget = CacheProvider.changeStateToNew(compositionElementTarget);
124 instanceElementMigrate = CacheProvider.changeStateToNew(instanceElementMigrate);
127 listener.migratePrecheck(messageId, compositionElement, compositionElementTarget,
128 instanceElement, instanceElementMigrate);
131 for (var elementId : toDelete) {
132 var compositionDtoTarget =
133 new CompositionElementDto(compositionTargetId,
134 automationComposition.getElements().get(elementId).getDefinition(),
135 Map.of(), Map.of(), ElementState.REMOVED);
136 var instanceDtoTarget =
137 new InstanceElementDto(automationComposition.getInstanceId(), elementId,
138 Map.of(), Map.of(), ElementState.REMOVED);
140 listener.migratePrecheck(messageId, compositionElementMap.get(elementId), compositionDtoTarget,
141 instanceElementMap.get(elementId), instanceDtoTarget);
146 * Handle AutomationComposition Prepare message.
148 * @param acPrepareMsg the AutomationCompositionPrepare message
150 public void handleAcPrepare(AutomationCompositionPrepare acPrepareMsg) {
151 if (acPrepareMsg.isPreDeploy()) {
152 for (var participantPrepare : acPrepareMsg.getParticipantList()) {
153 if (cacheProvider.getParticipantId().equals(participantPrepare.getParticipantId())) {
154 cacheProvider.initializeAutomationComposition(acPrepareMsg.getCompositionId(),
155 acPrepareMsg.getAutomationCompositionId(), participantPrepare, DeployState.UNDEPLOYED,
157 callParticipanPrepare(acPrepareMsg.getMessageId(), participantPrepare.getAcElementList(),
158 acPrepareMsg.getAutomationCompositionId());
162 var automationComposition =
163 cacheProvider.getAutomationComposition(acPrepareMsg.getAutomationCompositionId());
164 automationComposition.setSubState(SubState.REVIEWING);
165 callParticipanReview(acPrepareMsg.getMessageId(), automationComposition);
169 private void callParticipanPrepare(UUID messageId, List<AcElementDeploy> acElementList, UUID instanceId) {
170 var automationComposition = cacheProvider.getAutomationComposition(instanceId);
171 for (var elementDeploy : acElementList) {
172 var element = automationComposition.getElements().get(elementDeploy.getId());
173 var compositionInProperties = cacheProvider
174 .getCommonProperties(automationComposition.getCompositionId(), element.getDefinition());
175 var compositionElement = cacheProvider.createCompositionElementDto(automationComposition.getCompositionId(),
176 element, compositionInProperties);
177 var instanceElement = new InstanceElementDto(instanceId, elementDeploy.getId(),
178 elementDeploy.getProperties(), element.getOutProperties());
179 listener.prepare(messageId, compositionElement, instanceElement);
183 private void callParticipanReview(UUID messageId, AutomationComposition automationComposition) {
184 for (var element : automationComposition.getElements().values()) {
185 var compositionInProperties = cacheProvider
186 .getCommonProperties(automationComposition.getCompositionId(), element.getDefinition());
187 element.setSubState(SubState.REVIEWING);
188 var compositionElement = cacheProvider.createCompositionElementDto(automationComposition.getCompositionId(),
189 element, compositionInProperties);
190 var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(),
191 element.getProperties(), element.getOutProperties());
192 listener.review(messageId, compositionElement, instanceElement);