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());
224 * @param execIdentificationId the identification Id
225 * @param messageId the messageId
227 public void cleanExecution(UUID execIdentificationId, UUID messageId) {
228 var process = executionMap.get(execIdentificationId);
229 if (process != null) {
230 if (!process.isDone()) {
231 process.cancel(true);
233 executionMap.remove(execIdentificationId);
235 cacheProvider.getMsgIdentification().put(execIdentificationId, messageId);
239 * Handles prime a Composition Definition.
241 * @param messageId the messageId
242 * @param composition the composition
244 public void prime(UUID messageId, CompositionDto composition) {
245 cleanExecution(composition.compositionId(), messageId);
246 var result = executor.submit(() -> this.primeProcess(composition));
247 executionMap.put(composition.compositionId(), result);
250 private void primeProcess(CompositionDto composition) {
252 listener.prime(composition);
253 executionMap.remove(composition.compositionId());
254 } catch (PfModelException e) {
255 LOGGER.error("Composition Defintion prime failed {} {}", composition.compositionId(), e.getMessage());
256 intermediaryApi.updateCompositionState(composition.compositionId(), AcTypeState.COMMISSIONED,
257 StateChangeResult.FAILED, "Composition Defintion prime failed");
262 * Handles deprime a Composition Definition.
264 * @param messageId the messageId
265 * @param composition the composition
267 public void deprime(UUID messageId, CompositionDto composition) {
268 cleanExecution(composition.compositionId(), messageId);
269 var result = executor.submit(() -> this.deprimeProcess(composition));
270 executionMap.put(composition.compositionId(), result);
273 private void deprimeProcess(CompositionDto composition) {
275 listener.deprime(composition);
276 executionMap.remove(composition.compositionId());
277 } catch (PfModelException e) {
278 LOGGER.error("Composition Defintion deprime failed {} {}", composition.compositionId(), e.getMessage());
279 intermediaryApi.updateCompositionState(composition.compositionId(), AcTypeState.PRIMED,
280 StateChangeResult.FAILED, "Composition Defintion deprime failed");
285 * Closes this stream and releases any system resources associated
286 * with it. If the stream is already closed then invoking this
287 * method has no effect.
289 * @throws IOException if an I/O error occurs
292 public void close() throws IOException {
297 * Handles AutomationComposition Migration.
299 * @param messageId the messageId
300 * @param compositionElement the information of the Automation Composition Definition Element
301 * @param compositionElementTarget the information of the Automation Composition Definition Element Target
302 * @param instanceElement the information of the Automation Composition Instance Element
303 * @param instanceElementMigrate the information of the Automation Composition Instance Element updated
304 * @param stage the stage
306 public void migrate(UUID messageId, CompositionElementDto compositionElement,
307 CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement,
308 InstanceElementDto instanceElementMigrate, int stage) {
309 cleanExecution(instanceElement.elementId(), messageId);
310 var result = executor.submit(() ->
311 this.migrateProcess(compositionElement, compositionElementTarget,
312 instanceElement, instanceElementMigrate, stage));
313 executionMap.put(instanceElement.elementId(), result);
316 private void migrateProcess(CompositionElementDto compositionElement,
317 CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement,
318 InstanceElementDto instanceElementMigrate, int stage) {
320 listener.migrate(compositionElement, compositionElementTarget,
321 instanceElement, instanceElementMigrate, stage);
322 } catch (PfModelException e) {
323 LOGGER.error("Automation composition element migrate failed {} {}",
324 instanceElement.elementId(), e.getMessage());
325 intermediaryApi.updateAutomationCompositionElementState(
326 instanceElement.instanceId(), instanceElement.elementId(), DeployState.DEPLOYED,
327 null, StateChangeResult.FAILED, "Automation composition element migrate failed");
329 executionMap.remove(instanceElement.elementId());
333 * Handles AutomationComposition Migration Precheck.
335 * @param messageId the messageId
336 * @param compositionElement the information of the Automation Composition Definition Element
337 * @param compositionElementTarget the information of the Automation Composition Definition Element Target
338 * @param instanceElement the information of the Automation Composition Instance Element
339 * @param instanceElementMigrate the information of the Automation Composition Instance Element updated
341 public void migratePrecheck(UUID messageId, CompositionElementDto compositionElement,
342 CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement,
343 InstanceElementDto instanceElementMigrate) {
344 cleanExecution(instanceElement.elementId(), messageId);
345 var result = executor.submit(() ->
346 this.migratePrecheckProcess(compositionElement, compositionElementTarget, instanceElement,
347 instanceElementMigrate));
348 executionMap.put(instanceElement.elementId(), result);
351 private void migratePrecheckProcess(CompositionElementDto compositionElement,
352 CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement,
353 InstanceElementDto instanceElementMigrate) {
355 listener.migratePrecheck(compositionElement, compositionElementTarget, instanceElement,
356 instanceElementMigrate);
357 } catch (PfModelException e) {
358 LOGGER.error("Automation composition element migrate precheck failed {} {}",
359 instanceElement.elementId(), e.getMessage());
360 intermediaryApi.updateAutomationCompositionElementState(
361 instanceElement.instanceId(), instanceElement.elementId(), DeployState.DEPLOYED,
362 null, StateChangeResult.FAILED, "Automation composition element migrate precheck failed");
364 executionMap.remove(instanceElement.elementId());
368 * Handles AutomationComposition Prepare Post Deploy.
370 * @param messageId the messageId
371 * @param compositionElement the information of the Automation Composition Definition Element
372 * @param instanceElement the information of the Automation Composition Instance Element
374 public void review(UUID messageId, CompositionElementDto compositionElement,
375 InstanceElementDto instanceElement) {
376 cleanExecution(instanceElement.elementId(), messageId);
377 var result = executor.submit(() -> this.reviewProcess(compositionElement, instanceElement));
378 executionMap.put(instanceElement.elementId(), result);
381 private void reviewProcess(CompositionElementDto compositionElement, InstanceElementDto instanceElement) {
383 listener.review(compositionElement, instanceElement);
384 } catch (PfModelException e) {
385 LOGGER.error("Automation composition element Review failed {} {}",
386 instanceElement.elementId(), e.getMessage());
387 intermediaryApi.updateAutomationCompositionElementState(
388 instanceElement.instanceId(), instanceElement.elementId(), DeployState.DEPLOYED,
389 null, StateChangeResult.FAILED, "Automation composition element Review failed");
391 executionMap.remove(instanceElement.elementId());
395 * Handles AutomationComposition Prepare Pre Deploy.
397 * @param messageId the messageId
398 * @param compositionElement the information of the Automation Composition Definition Element
399 * @param instanceElement the information of the Automation Composition Instance Element
401 public void prepare(UUID messageId, CompositionElementDto compositionElement,
402 InstanceElementDto instanceElement) {
403 cleanExecution(instanceElement.elementId(), messageId);
404 var result = executor.submit(() -> this.prepareProcess(compositionElement, instanceElement));
405 executionMap.put(instanceElement.elementId(), result);
408 private void prepareProcess(CompositionElementDto compositionElement, InstanceElementDto instanceElement) {
410 listener.prepare(compositionElement, instanceElement);
411 } catch (PfModelException e) {
412 LOGGER.error("Automation composition element prepare Pre Deploy failed {} {}",
413 instanceElement.elementId(), e.getMessage());
414 intermediaryApi.updateAutomationCompositionElementState(
415 instanceElement.instanceId(), instanceElement.elementId(), DeployState.UNDEPLOYED,
416 null, StateChangeResult.FAILED, "Automation composition element prepare Pre Deploy failed");
418 executionMap.remove(instanceElement.elementId());