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 io.opentelemetry.context.Context;
24 import java.io.Closeable;
25 import java.io.IOException;
27 import java.util.UUID;
28 import java.util.concurrent.ConcurrentHashMap;
29 import java.util.concurrent.ExecutorService;
30 import java.util.concurrent.Executors;
31 import java.util.concurrent.Future;
32 import lombok.RequiredArgsConstructor;
33 import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener;
34 import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto;
35 import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto;
36 import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto;
37 import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
38 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
39 import org.onap.policy.clamp.models.acm.concepts.DeployState;
40 import org.onap.policy.clamp.models.acm.concepts.LockState;
41 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
42 import org.onap.policy.models.base.PfModelException;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45 import org.springframework.stereotype.Component;
48 @RequiredArgsConstructor
49 public class ThreadHandler implements Closeable {
50 private static final Logger LOGGER = LoggerFactory.getLogger(ThreadHandler.class);
52 private final AutomationCompositionElementListener listener;
53 private final ParticipantIntermediaryApi intermediaryApi;
54 private final CacheProvider cacheProvider;
56 private final Map<UUID, Future> executionMap = new ConcurrentHashMap<>();
58 private final ExecutorService executor =
59 Context.taskWrapping(Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()));
62 * Handle a deploy on a automation composition element.
64 * @param messageId the messageId
65 * @param compositionElement the information of the Automation Composition Definition Element
66 * @param instanceElement the information of the Automation Composition Instance Element
68 public void deploy(UUID messageId, CompositionElementDto compositionElement, InstanceElementDto instanceElement) {
69 cleanExecution(instanceElement.elementId(), messageId);
70 var result = executor.submit(() -> this.deployProcess(compositionElement, instanceElement));
71 executionMap.put(instanceElement.elementId(), result);
74 private void deployProcess(CompositionElementDto compositionElement, InstanceElementDto instanceElement) {
76 listener.deploy(compositionElement, instanceElement);
77 } catch (PfModelException e) {
78 LOGGER.error("Automation composition element deploy failed {} {}", instanceElement.elementId(),
80 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
81 instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
82 "Automation composition element deploy failed");
84 executionMap.remove(instanceElement.elementId());
88 * Handle an udeploy on a automation composition element.
90 * @param messageId the messageId
91 * @param compositionElement the information of the Automation Composition Definition Element
92 * @param instanceElement the information of the Automation Composition Instance Element
94 public void undeploy(UUID messageId, CompositionElementDto compositionElement, InstanceElementDto instanceElement) {
95 cleanExecution(instanceElement.elementId(), messageId);
96 var result = executor.submit(() -> this.undeployProcess(compositionElement, instanceElement));
97 executionMap.put(instanceElement.elementId(), result);
100 private void undeployProcess(CompositionElementDto compositionElement, InstanceElementDto instanceElement) {
102 listener.undeploy(compositionElement, instanceElement);
103 } catch (PfModelException e) {
105 "Automation composition element undeploy failed {} {}", instanceElement.elementId(), e.getMessage());
106 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
107 instanceElement.elementId(), DeployState.DEPLOYED, null,
108 StateChangeResult.FAILED, "Automation composition element undeploy failed");
110 executionMap.remove(instanceElement.elementId());
114 * Handle a automation composition element lock.
116 * @param messageId the messageId
117 * @param compositionElement the information of the Automation Composition Definition Element
118 * @param instanceElement the information of the Automation Composition Instance Element
120 public void lock(UUID messageId, CompositionElementDto compositionElement, InstanceElementDto instanceElement) {
121 cleanExecution(instanceElement.elementId(), messageId);
122 var result = executor.submit(() -> this.lockProcess(compositionElement, instanceElement));
123 executionMap.put(instanceElement.elementId(), result);
126 private void lockProcess(CompositionElementDto compositionElement, InstanceElementDto instanceElement) {
128 listener.lock(compositionElement, instanceElement);
129 } catch (PfModelException e) {
130 LOGGER.error("Automation composition element lock failed {} {}",
131 instanceElement.elementId(), e.getMessage());
132 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
133 instanceElement.elementId(), null, LockState.UNLOCKED, StateChangeResult.FAILED,
134 "Automation composition element lock failed");
136 executionMap.remove(instanceElement.elementId());
140 * Handle a automation composition element unlock.
142 * @param messageId the messageId
143 * @param compositionElement the information of the Automation Composition Definition Element
144 * @param instanceElement the information of the Automation Composition Instance Element
146 public void unlock(UUID messageId, CompositionElementDto compositionElement, InstanceElementDto instanceElement) {
147 cleanExecution(instanceElement.elementId(), messageId);
148 var result = executor.submit(() -> this.unlockProcess(compositionElement, instanceElement));
149 executionMap.put(instanceElement.elementId(), result);
152 private void unlockProcess(CompositionElementDto compositionElement, InstanceElementDto instanceElement) {
154 listener.unlock(compositionElement, instanceElement);
155 } catch (PfModelException e) {
156 LOGGER.error("Automation composition element unlock failed {} {}",
157 instanceElement.elementId(), e.getMessage());
158 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
159 instanceElement.elementId(), null, LockState.LOCKED, StateChangeResult.FAILED,
160 "Automation composition element unlock failed");
162 executionMap.remove(instanceElement.elementId());
166 * Handle a automation composition element delete.
168 * @param messageId the messageId
169 * @param compositionElement the information of the Automation Composition Definition Element
170 * @param instanceElement the information of the Automation Composition Instance Element
172 public void delete(UUID messageId, CompositionElementDto compositionElement, InstanceElementDto instanceElement) {
173 cleanExecution(instanceElement.elementId(), messageId);
174 var result = executor.submit(() -> this.deleteProcess(compositionElement, instanceElement));
175 executionMap.put(instanceElement.elementId(), result);
178 private void deleteProcess(CompositionElementDto compositionElement, InstanceElementDto instanceElement) {
180 listener.delete(compositionElement, instanceElement);
181 } catch (PfModelException e) {
182 LOGGER.error("Automation composition element delete failed {} {}",
183 instanceElement.elementId(), e.getMessage());
184 intermediaryApi.updateAutomationCompositionElementState(
185 instanceElement.instanceId(), instanceElement.elementId(), DeployState.UNDEPLOYED, null,
186 StateChangeResult.FAILED, "Automation composition element delete failed");
188 executionMap.remove(instanceElement.elementId());
192 * Handle a automation composition element properties update.
194 * @param messageId the messageId
195 * @param compositionElement the information of the Automation Composition Definition Element
196 * @param instanceElement the information of the Automation Composition Instance Element
197 * @param instanceElementUpdated the information of the Automation Composition Instance Element updated
199 public void update(UUID messageId, CompositionElementDto compositionElement, InstanceElementDto instanceElement,
200 InstanceElementDto instanceElementUpdated) {
201 cleanExecution(instanceElement.elementId(), messageId);
202 var result = executor.submit(() ->
203 this.updateProcess(compositionElement, instanceElement, instanceElementUpdated));
204 executionMap.put(instanceElement.elementId(), result);
207 private void updateProcess(CompositionElementDto compositionElement, InstanceElementDto instanceElement,
208 InstanceElementDto instanceElementUpdated) {
210 listener.update(compositionElement, instanceElement, instanceElementUpdated);
211 } catch (PfModelException e) {
212 LOGGER.error("Automation composition element update failed {} {}",
213 instanceElement.elementId(), e.getMessage());
214 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
215 instanceElement.elementId(), DeployState.DEPLOYED, null,
216 StateChangeResult.FAILED, "Automation composition element update failed");
218 executionMap.remove(instanceElement.elementId());
221 private void cleanExecution(UUID execIdentificationId, UUID messageId) {
222 var process = executionMap.get(execIdentificationId);
223 if (process != null) {
224 if (!process.isDone()) {
225 process.cancel(true);
227 executionMap.remove(execIdentificationId);
229 cacheProvider.getMsgIdentification().put(execIdentificationId, messageId);
233 * Handles prime a Composition Definition.
235 * @param messageId the messageId
236 * @param composition the composition
238 public void prime(UUID messageId, CompositionDto composition) {
239 cleanExecution(composition.compositionId(), messageId);
240 var result = executor.submit(() -> this.primeProcess(composition));
241 executionMap.put(composition.compositionId(), result);
244 private void primeProcess(CompositionDto composition) {
246 listener.prime(composition);
247 executionMap.remove(composition.compositionId());
248 } catch (PfModelException e) {
249 LOGGER.error("Composition Defintion prime failed {} {}", composition.compositionId(), e.getMessage());
250 intermediaryApi.updateCompositionState(composition.compositionId(), AcTypeState.COMMISSIONED,
251 StateChangeResult.FAILED, "Composition Defintion prime failed");
256 * Handles deprime a Composition Definition.
258 * @param messageId the messageId
259 * @param composition the composition
261 public void deprime(UUID messageId, CompositionDto composition) {
262 cleanExecution(composition.compositionId(), messageId);
263 var result = executor.submit(() -> this.deprimeProcess(composition));
264 executionMap.put(composition.compositionId(), result);
267 private void deprimeProcess(CompositionDto composition) {
269 listener.deprime(composition);
270 executionMap.remove(composition.compositionId());
271 } catch (PfModelException e) {
272 LOGGER.error("Composition Defintion deprime failed {} {}", composition.compositionId(), e.getMessage());
273 intermediaryApi.updateCompositionState(composition.compositionId(), AcTypeState.PRIMED,
274 StateChangeResult.FAILED, "Composition Defintion deprime failed");
279 * Closes this stream and releases any system resources associated
280 * with it. If the stream is already closed then invoking this
281 * method has no effect.
283 * @throws IOException if an I/O error occurs
286 public void close() throws IOException {
291 * Handles AutomationComposition Migration.
293 * @param messageId the messageId
294 * @param compositionElement the information of the Automation Composition Definition Element
295 * @param compositionElementTarget the information of the Automation Composition Definition Element Target
296 * @param instanceElement the information of the Automation Composition Instance Element
297 * @param instanceElementMigrate the information of the Automation Composition Instance Element updated
299 public void migrate(UUID messageId, CompositionElementDto compositionElement,
300 CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement,
301 InstanceElementDto instanceElementMigrate) {
302 cleanExecution(instanceElement.elementId(), messageId);
303 var result = executor.submit(() ->
304 this.migrateProcess(compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate));
305 executionMap.put(instanceElement.elementId(), result);
308 private void migrateProcess(CompositionElementDto compositionElement,
309 CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement,
310 InstanceElementDto instanceElementMigrate) {
312 listener.migrate(compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate);
313 } catch (PfModelException e) {
314 LOGGER.error("Automation composition element migrate failed {} {}",
315 instanceElement.elementId(), e.getMessage());
316 intermediaryApi.updateAutomationCompositionElementState(
317 instanceElement.instanceId(), instanceElement.elementId(), DeployState.DEPLOYED,
318 null, StateChangeResult.FAILED, "Automation composition element migrate failed");
320 executionMap.remove(instanceElement.elementId());