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.runtime.instantiation;
26 import java.util.UUID;
27 import javax.validation.Valid;
28 import javax.ws.rs.core.Response;
29 import javax.ws.rs.core.Response.Status;
30 import lombok.AllArgsConstructor;
31 import org.onap.policy.clamp.acm.runtime.supervision.SupervisionAcHandler;
32 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
33 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
34 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
35 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions;
36 import org.onap.policy.clamp.models.acm.concepts.DeployState;
37 import org.onap.policy.clamp.models.acm.concepts.LockState;
38 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AcInstanceStateUpdate;
39 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse;
40 import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
41 import org.onap.policy.clamp.models.acm.persistence.provider.AcInstanceStateResolver;
42 import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
43 import org.onap.policy.clamp.models.acm.utils.AcmUtils;
44 import org.onap.policy.common.parameters.BeanValidationResult;
45 import org.onap.policy.common.parameters.ObjectValidationResult;
46 import org.onap.policy.common.parameters.ValidationStatus;
47 import org.onap.policy.models.base.PfModelRuntimeException;
48 import org.springframework.stereotype.Service;
49 import org.springframework.transaction.annotation.Transactional;
52 * This class is dedicated to the Instantiation of Commissioned automation composition.
57 public class AutomationCompositionInstantiationProvider {
58 private static final String DO_NOT_MATCH = " do not match with ";
60 private final AutomationCompositionProvider automationCompositionProvider;
61 private final AcDefinitionProvider acDefinitionProvider;
62 private final AcInstanceStateResolver acInstanceStateResolver;
63 private final SupervisionAcHandler supervisionAcHandler;
66 * Create automation composition.
68 * @param compositionId The UUID of the automation composition definition
69 * @param automationComposition the automation composition
70 * @return the result of the instantiation operation
72 public InstantiationResponse createAutomationComposition(UUID compositionId,
73 AutomationComposition automationComposition) {
74 if (!compositionId.equals(automationComposition.getCompositionId())) {
75 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
76 automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
78 var checkAutomationCompositionOpt =
79 automationCompositionProvider.findAutomationComposition(automationComposition.getKey().asIdentifier());
80 if (checkAutomationCompositionOpt.isPresent()) {
81 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
82 automationComposition.getKey().asIdentifier() + " already defined");
85 var validationResult = validateAutomationComposition(automationComposition);
86 if (!validationResult.isValid()) {
87 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
89 automationComposition = automationCompositionProvider.createAutomationComposition(automationComposition);
91 var response = new InstantiationResponse();
92 response.setInstanceId(automationComposition.getInstanceId());
93 response.setAffectedAutomationComposition(automationComposition.getKey().asIdentifier());
99 * Update automation composition.
101 * @param compositionId The UUID of the automation composition definition
102 * @param automationComposition the automation composition
103 * @return the result of the update
105 public InstantiationResponse updateAutomationComposition(UUID compositionId,
106 AutomationComposition automationComposition) {
107 var response = new InstantiationResponse();
108 var instanceId = automationComposition.getInstanceId();
109 var acToUpdate = automationCompositionProvider.getAutomationComposition(instanceId);
110 if (!compositionId.equals(acToUpdate.getCompositionId())) {
111 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
112 automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
114 if (DeployState.UNDEPLOYED.equals(acToUpdate.getDeployState())) {
115 acToUpdate.setElements(automationComposition.getElements());
116 acToUpdate.setName(automationComposition.getName());
117 acToUpdate.setVersion(automationComposition.getVersion());
118 acToUpdate.setDescription(automationComposition.getDescription());
119 acToUpdate.setDerivedFrom(automationComposition.getDerivedFrom());
120 var validationResult = validateAutomationComposition(acToUpdate);
121 if (!validationResult.isValid()) {
122 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
124 automationComposition = automationCompositionProvider.updateAutomationComposition(acToUpdate);
125 response.setInstanceId(instanceId);
126 response.setAffectedAutomationComposition(automationComposition.getKey().asIdentifier());
129 } else if (DeployState.DEPLOYED.equals(acToUpdate.getDeployState())
130 && LockState.LOCKED.equals(acToUpdate.getLockState())) {
131 return updateDeployedAutomationComposition(compositionId, automationComposition, acToUpdate);
133 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
134 "Not allowed to update in the state " + acToUpdate.getDeployState());
138 * Update deployed AC Element properties.
140 * @param compositionId The UUID of the automation composition definition
141 * @param automationComposition the automation composition
142 * @param acToBeUpdated the composition to be updated
143 * @return the result of the update
145 public InstantiationResponse updateDeployedAutomationComposition(UUID compositionId,
146 AutomationComposition automationComposition,
147 AutomationComposition acToBeUpdated) {
149 // Iterate and update the element property values
150 for (Map.Entry<UUID, AutomationCompositionElement> dbAcElement : acToBeUpdated.getElements().entrySet()) {
151 var elementId = dbAcElement.getKey();
152 if (automationComposition.getElements().containsKey(elementId)) {
153 dbAcElement.getValue().getProperties().putAll(automationComposition.getElements().get(elementId)
157 // Publish property update event to the participants
158 supervisionAcHandler.update(acToBeUpdated);
160 var validationResult = validateAutomationComposition(acToBeUpdated);
161 if (!validationResult.isValid()) {
162 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
164 automationComposition = automationCompositionProvider.updateAutomationComposition(acToBeUpdated);
165 var response = new InstantiationResponse();
166 var instanceId = automationComposition.getInstanceId();
167 response.setInstanceId(instanceId);
168 response.setAffectedAutomationComposition(automationComposition.getKey().asIdentifier());
174 * Validate AutomationComposition.
176 * @param automationComposition AutomationComposition to validate
177 * @return the result of validation
179 private BeanValidationResult validateAutomationComposition(AutomationComposition automationComposition) {
181 var result = new BeanValidationResult("AutomationComposition", automationComposition);
182 var acDefinitionOpt = acDefinitionProvider.findAcDefinition(automationComposition.getCompositionId());
183 if (acDefinitionOpt.isEmpty()) {
184 result.addResult(new ObjectValidationResult("ServiceTemplate", "", ValidationStatus.INVALID,
185 "Commissioned automation composition definition not found"));
188 if (!AcTypeState.PRIMED.equals(acDefinitionOpt.get().getState())) {
189 result.addResult(new ObjectValidationResult("ServiceTemplate", acDefinitionOpt.get().getState(),
190 ValidationStatus.INVALID, "Commissioned automation composition definition not primed"));
193 result.addResult(AcmUtils.validateAutomationComposition(automationComposition,
194 acDefinitionOpt.get().getServiceTemplate()));
196 if (result.isValid()) {
197 for (var element : automationComposition.getElements().values()) {
198 var name = element.getDefinition().getName();
199 var participantId = acDefinitionOpt.get().getElementStateMap().get(name).getParticipantId();
200 element.setParticipantId(participantId);
208 * Get Automation Composition.
210 * @param compositionId The UUID of the automation composition definition
211 * @param instanceId The UUID of the automation composition instance
212 * @return the Automation Composition
214 @Transactional(readOnly = true)
215 public AutomationComposition getAutomationComposition(UUID compositionId, UUID instanceId) {
216 var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
217 if (!automationComposition.getCompositionId().equals(compositionId)) {
218 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
219 automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
221 return automationComposition;
225 * Delete the automation composition with the given name and version.
227 * @param compositionId The UUID of the automation composition definition
228 * @param instanceId The UUID of the automation composition instance
229 * @return the result of the deletion
231 public InstantiationResponse deleteAutomationComposition(UUID compositionId, UUID instanceId) {
232 var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
233 if (!compositionId.equals(automationComposition.getCompositionId())) {
234 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
235 automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
237 if (!DeployState.UNDEPLOYED.equals(automationComposition.getDeployState())) {
238 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
239 "Automation composition state is still " + automationComposition.getDeployState());
241 var response = new InstantiationResponse();
242 var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId());
243 supervisionAcHandler.delete(automationComposition, acDefinition);
244 response.setInstanceId(automationComposition.getInstanceId());
245 response.setAffectedAutomationComposition(automationComposition.getKey().asIdentifier());
250 * Get the requested automation compositions.
252 * @param name the name of the automation composition to get, null for all automation compositions
253 * @param version the version of the automation composition to get, null for all automation compositions
254 * @return the automation compositions
256 @Transactional(readOnly = true)
257 public AutomationCompositions getAutomationCompositions(UUID compositionId, String name, String version) {
258 var automationCompositions = new AutomationCompositions();
259 automationCompositions.setAutomationCompositionList(
260 automationCompositionProvider.getAutomationCompositions(compositionId, name, version));
262 return automationCompositions;
266 * Handle Composition Instance State.
268 * @param compositionId the compositionId
269 * @param instanceId the instanceId
270 * @param acInstanceStateUpdate the AcInstanceStateUpdate
272 public void compositionInstanceState(UUID compositionId, UUID instanceId,
273 @Valid AcInstanceStateUpdate acInstanceStateUpdate) {
274 var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
275 if (!compositionId.equals(automationComposition.getCompositionId())) {
276 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
277 automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
279 var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId());
280 var result = acInstanceStateResolver.resolve(acInstanceStateUpdate.getDeployOrder(),
281 acInstanceStateUpdate.getLockOrder(), automationComposition.getDeployState(),
282 automationComposition.getLockState());
285 supervisionAcHandler.deploy(automationComposition, acDefinition);
289 supervisionAcHandler.undeploy(automationComposition, acDefinition);
293 supervisionAcHandler.lock(automationComposition, acDefinition);
297 supervisionAcHandler.unlock(automationComposition, acDefinition);
301 throw new PfModelRuntimeException(Status.BAD_REQUEST, "Not valid " + acInstanceStateUpdate);