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.io.Closeable;
24 import java.io.IOException;
25 import java.util.List;
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.ParticipantIntermediaryApi;
35 import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
36 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
37 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
38 import org.onap.policy.clamp.models.acm.concepts.DeployState;
39 import org.onap.policy.clamp.models.acm.concepts.LockState;
40 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
41 import org.onap.policy.models.base.PfModelException;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44 import org.springframework.stereotype.Component;
47 @RequiredArgsConstructor
48 public class ThreadHandler implements Closeable {
49 private static final Logger LOGGER = LoggerFactory.getLogger(ThreadHandler.class);
51 private final AutomationCompositionElementListener listener;
52 private final ParticipantIntermediaryApi intermediaryApi;
53 private final CacheProvider cacheProvider;
55 private final Map<UUID, Future> executionMap = new ConcurrentHashMap<>();
57 private final ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
60 * Handle an update on a automation composition element.
62 * @param messageId the messageId
63 * @param instanceId the automationComposition Id
64 * @param element the information on the automation composition element
65 * @param properties properties Map
67 public void deploy(UUID messageId, UUID instanceId, AcElementDeploy element, Map<String, Object> properties) {
68 cleanExecution(element.getId(), messageId);
69 var result = executor.submit(() -> this.deployProcess(instanceId, element, properties));
70 executionMap.put(element.getId(), result);
73 private void deployProcess(UUID instanceId, AcElementDeploy element, Map<String, Object> properties) {
75 listener.deploy(instanceId, element, properties);
76 } catch (PfModelException e) {
77 LOGGER.error("Automation composition element deploy failed {} {}", instanceId, e.getMessage());
78 intermediaryApi.updateAutomationCompositionElementState(instanceId, element.getId(), DeployState.UNDEPLOYED,
79 null, StateChangeResult.FAILED, "Automation composition element deploy failed");
81 executionMap.remove(element.getId());
85 * Handle a automation composition element state change.
87 * @param messageId the messageId
88 * @param instanceId the automationComposition Id
89 * @param elementId the ID of the automation composition element
91 public void undeploy(UUID messageId, UUID instanceId, UUID elementId) {
92 cleanExecution(elementId, messageId);
93 var result = executor.submit(() -> this.undeployProcess(instanceId, elementId));
94 executionMap.put(elementId, result);
97 private void undeployProcess(UUID instanceId, UUID elementId) {
99 listener.undeploy(instanceId, elementId);
100 } catch (PfModelException e) {
101 LOGGER.error("Automation composition element undeploy failed {} {}", instanceId, e.getMessage());
102 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, DeployState.DEPLOYED, null,
103 StateChangeResult.FAILED, "Automation composition element undeploy failed");
105 executionMap.remove(elementId);
109 * Handle a automation composition element lock.
111 * @param messageId the messageId
112 * @param instanceId the automationComposition Id
113 * @param elementId the ID of the automation composition element
115 public void lock(UUID messageId, UUID instanceId, UUID elementId) {
116 cleanExecution(elementId, messageId);
117 var result = executor.submit(() -> this.lockProcess(instanceId, elementId));
118 executionMap.put(elementId, result);
121 private void lockProcess(UUID instanceId, UUID elementId) {
123 listener.lock(instanceId, elementId);
124 } catch (PfModelException e) {
125 LOGGER.error("Automation composition element lock failed {} {}", instanceId, e.getMessage());
126 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, null, LockState.UNLOCKED,
127 StateChangeResult.FAILED, "Automation composition element lock failed");
129 executionMap.remove(elementId);
133 * Handle a automation composition element unlock.
135 * @param messageId the messageId
136 * @param instanceId the automationComposition Id
137 * @param elementId the ID of the automation composition element
139 public void unlock(UUID messageId, UUID instanceId, UUID elementId) {
140 cleanExecution(elementId, messageId);
141 var result = executor.submit(() -> this.unlockProcess(instanceId, elementId));
142 executionMap.put(elementId, result);
145 private void unlockProcess(UUID instanceId, UUID elementId) {
147 listener.unlock(instanceId, elementId);
148 } catch (PfModelException e) {
149 LOGGER.error("Automation composition element unlock failed {} {}", instanceId, e.getMessage());
150 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, null, LockState.LOCKED,
151 StateChangeResult.FAILED, "Automation composition element unlock failed");
153 executionMap.remove(elementId);
157 * Handle a automation composition element delete.
159 * @param messageId the messageId
160 * @param instanceId the automationComposition Id
161 * @param elementId the ID of the automation composition element
163 public void delete(UUID messageId, UUID instanceId, UUID elementId) {
164 cleanExecution(elementId, messageId);
165 var result = executor.submit(() -> this.deleteProcess(instanceId, elementId));
166 executionMap.put(elementId, result);
169 private void deleteProcess(UUID instanceId, UUID elementId) {
171 listener.delete(instanceId, elementId);
172 } catch (PfModelException e) {
173 LOGGER.error("Automation composition element delete failed {} {}", instanceId, e.getMessage());
174 intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, DeployState.UNDEPLOYED, null,
175 StateChangeResult.FAILED, "Automation composition element delete failed");
177 executionMap.remove(elementId);
181 * Handle a automation composition element properties update.
183 * @param messageId the messageId
184 * @param instanceId the automationComposition Id
185 * @param element the information on the automation composition element
186 * @param properties properties Map
188 public void update(UUID messageId, UUID instanceId, AcElementDeploy element, Map<String, Object> properties) {
189 cleanExecution(element.getId(), messageId);
190 var result = executor.submit(() -> this.updateProcess(instanceId, element, properties));
191 executionMap.put(element.getId(), result);
194 private void updateProcess(UUID instanceId, AcElementDeploy element, Map<String, Object> properties) {
196 listener.update(instanceId, element, properties);
197 } catch (PfModelException e) {
198 LOGGER.error("Automation composition element update failed {} {}", instanceId, e.getMessage());
199 intermediaryApi.updateAutomationCompositionElementState(instanceId, element.getId(), DeployState.DEPLOYED,
200 null, StateChangeResult.FAILED, "Automation composition element update failed");
202 executionMap.remove(element.getId());
205 private void cleanExecution(UUID execIdentificationId, UUID messageId) {
206 var process = executionMap.get(execIdentificationId);
207 if (process != null) {
208 if (!process.isDone()) {
209 process.cancel(true);
211 executionMap.remove(execIdentificationId);
213 cacheProvider.getMsgIdentification().put(execIdentificationId, messageId);
217 * Handles prime a Composition Definition.
219 * @param messageId the messageId
220 * @param compositionId the compositionId
221 * @param list the list of AutomationCompositionElementDefinition
223 public void prime(UUID messageId, UUID compositionId, List<AutomationCompositionElementDefinition> list) {
224 cleanExecution(compositionId, messageId);
225 var result = executor.submit(() -> this.primeProcess(compositionId, list));
226 executionMap.put(compositionId, result);
229 private void primeProcess(UUID compositionId, List<AutomationCompositionElementDefinition> list) {
231 listener.prime(compositionId, list);
232 executionMap.remove(compositionId);
233 } catch (PfModelException e) {
234 LOGGER.error("Composition Defintion prime failed {} {}", compositionId, e.getMessage());
235 intermediaryApi.updateCompositionState(compositionId, AcTypeState.COMMISSIONED, StateChangeResult.FAILED,
236 "Composition Defintion prime failed");
241 * Handles deprime a Composition Definition.
243 * @param messageId the messageId
244 * @param compositionId the compositionId
246 public void deprime(UUID messageId, UUID compositionId) {
247 cleanExecution(compositionId, messageId);
248 var result = executor.submit(() -> this.deprimeProcess(compositionId));
249 executionMap.put(compositionId, result);
252 private void deprimeProcess(UUID compositionId) {
254 listener.deprime(compositionId);
255 executionMap.remove(compositionId);
256 } catch (PfModelException e) {
257 LOGGER.error("Composition Defintion deprime failed {} {}", compositionId, e.getMessage());
258 intermediaryApi.updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.FAILED,
259 "Composition Defintion deprime failed");
265 * Closes this stream and releases any system resources associated
266 * with it. If the stream is already closed then invoking this
267 * method has no effect.
269 * @throws IOException if an I/O error occurs
272 public void close() throws IOException {