2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2021-2024 Nordix Foundation.
4 * ================================================================================
5 * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * SPDX-License-Identifier: Apache-2.0
20 * ============LICENSE_END=========================================================
23 package org.onap.policy.clamp.models.acm.persistence.provider;
25 import jakarta.ws.rs.core.Response;
26 import jakarta.ws.rs.core.Response.Status;
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.Optional;
30 import java.util.UUID;
31 import lombok.AllArgsConstructor;
32 import lombok.NonNull;
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.AutomationCompositionInfo;
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.concepts.SubState;
39 import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationComposition;
40 import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionElement;
41 import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionElementRepository;
42 import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionRepository;
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.ValidationStatus;
46 import org.onap.policy.models.base.PfModelRuntimeException;
47 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
48 import org.springframework.data.domain.Example;
49 import org.springframework.stereotype.Service;
50 import org.springframework.transaction.annotation.Isolation;
51 import org.springframework.transaction.annotation.Transactional;
54 * This class provides information on automation composition concepts in the database to callers.
59 public class AutomationCompositionProvider {
61 private final AutomationCompositionRepository automationCompositionRepository;
62 private final AutomationCompositionElementRepository acElementRepository;
65 * Get automation composition.
67 * @param instanceId the ID of the automation composition to get
68 * @return the automation composition found
70 @Transactional(readOnly = true)
71 public AutomationComposition getAutomationComposition(final UUID instanceId) {
72 var result = automationCompositionRepository.findById(instanceId.toString());
73 if (result.isEmpty()) {
74 throw new PfModelRuntimeException(Status.NOT_FOUND, "AutomationComposition not found");
76 return result.get().toAuthorative();
80 * Find automation composition.
82 * @param instanceId the ID of the automation composition to get
83 * @return the automation composition found
85 @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
86 public Optional<AutomationComposition> findAutomationComposition(final UUID instanceId) {
87 var result = automationCompositionRepository.findById(instanceId.toString());
88 return result.stream().map(JpaAutomationComposition::toAuthorative).findFirst();
92 * Find automation composition by automationCompositionId.
94 * @param automationCompositionId the ID of the automation composition to get
95 * @return the automation composition found
97 @Transactional(readOnly = true)
98 public Optional<AutomationComposition> findAutomationComposition(
99 final ToscaConceptIdentifier automationCompositionId) {
100 return automationCompositionRepository
101 .findOne(createExample(null, automationCompositionId.getName(), automationCompositionId.getVersion()))
102 .map(JpaAutomationComposition::toAuthorative);
106 * Create automation composition.
108 * @param automationComposition the automation composition to create
109 * @return the create automation composition
111 public AutomationComposition createAutomationComposition(final AutomationComposition automationComposition) {
112 automationComposition.setInstanceId(UUID.randomUUID());
113 AcmUtils.setCascadedState(automationComposition, DeployState.UNDEPLOYED, LockState.NONE);
114 var result = automationCompositionRepository.save(ProviderUtils.getJpaAndValidate(automationComposition,
115 JpaAutomationComposition::new, "automation composition"));
117 // Return the saved automation composition
118 return result.toAuthorative();
123 * Update automation composition state.
125 * @param acSource the automation composition to update
126 * @return the updated automation composition
128 public AutomationComposition updateAcState(final AutomationComposition acSource) {
129 var automationComposition = automationCompositionRepository
130 .getReferenceById(acSource.getInstanceId().toString());
131 automationComposition.fromAuthorativeBase(acSource);
132 var result = automationCompositionRepository.save(automationComposition);
133 automationCompositionRepository.flush();
134 // Return the saved automation composition
135 return result.toAuthorative();
139 * Update automation composition.
141 * @param automationComposition the automation composition to update
142 * @return the updated automation composition
144 public AutomationComposition updateAutomationComposition(
145 @NonNull final AutomationComposition automationComposition) {
146 var result = automationCompositionRepository.save(ProviderUtils.getJpaAndValidate(automationComposition,
147 JpaAutomationComposition::new, "automation composition"));
148 automationCompositionRepository.flush();
149 // Return the saved automation composition
150 return result.toAuthorative();
154 * Get all automation compositions by compositionId.
156 * @param compositionId the compositionId of the automation composition definition
157 * @return all automation compositions found
159 @Transactional(readOnly = true)
160 public List<AutomationComposition> getAcInstancesByCompositionId(UUID compositionId) {
162 .asEntityList(automationCompositionRepository.findByCompositionId(compositionId.toString()));
166 * Get all automation compositions in transition..
168 * @return all automation compositions found
170 @Transactional(readOnly = true)
171 public List<AutomationComposition> getAcInstancesInTransition() {
172 var jpaList = automationCompositionRepository.findByDeployStateIn(List.of(DeployState.DEPLOYING,
173 DeployState.UNDEPLOYING, DeployState.DELETING, DeployState.UPDATING, DeployState.MIGRATING));
174 jpaList.addAll(automationCompositionRepository.findByLockStateIn(
175 List.of(LockState.LOCKING, LockState.UNLOCKING)));
176 jpaList.addAll(automationCompositionRepository.findBySubStateIn(
177 List.of(SubState.PREPARING, SubState.MIGRATION_PRECHECKING, SubState.REVIEWING)));
178 return ProviderUtils.asEntityList(jpaList);
182 * Get automation compositions.
184 * @param name the name of the automation composition to get, null to get all automation compositions
185 * @param version the version of the automation composition to get, null to get all automation compositions
186 * @return the automation compositions found
188 @Transactional(readOnly = true)
189 public List<AutomationComposition> getAutomationCompositions(final UUID compositionId, final String name,
190 final String version) {
193 .asEntityList(automationCompositionRepository.findAll(createExample(compositionId, name, version)));
196 private Example<JpaAutomationComposition> createExample(final UUID compositionId, final String name,
197 final String version) {
198 var example = new JpaAutomationComposition();
199 example.setCompositionId(compositionId != null ? compositionId.toString() : null);
200 example.setName(name);
201 example.setVersion(version);
202 example.setInstanceId(null);
203 example.setElements(null);
204 example.setDeployState(null);
205 example.setLockState(null);
207 return Example.of(example);
211 * Delete a automation composition.
213 * @param instanceId the ID of the automation composition to get
214 * @return the automation composition deleted
216 public AutomationComposition deleteAutomationComposition(@NonNull final UUID instanceId) {
217 var jpaDeleteAutomationComposition = automationCompositionRepository.findById(instanceId.toString());
218 if (jpaDeleteAutomationComposition.isEmpty()) {
219 var errorMessage = "delete of automation composition \"" + instanceId
220 + "\" failed, automation composition does not exist";
221 throw new PfModelRuntimeException(Response.Status.NOT_FOUND, errorMessage);
224 automationCompositionRepository.deleteById(instanceId.toString());
226 return jpaDeleteAutomationComposition.get().toAuthorative();
232 * @param automationCompositionInfoList list of AutomationCompositionInfo
234 public void upgradeStates(@NonNull final List<AutomationCompositionInfo> automationCompositionInfoList) {
235 if (automationCompositionInfoList.isEmpty()) {
238 List<JpaAutomationCompositionElement> jpaList = new ArrayList<>();
239 for (var acInstance : automationCompositionInfoList) {
240 for (var element : acInstance.getElements()) {
241 var jpa = acElementRepository.getReferenceById(element.getAutomationCompositionElementId().toString());
242 jpa.setUseState(element.getUseState());
243 jpa.setOperationalState(element.getOperationalState());
244 jpa.setOutProperties(element.getOutProperties());
248 acElementRepository.saveAll(jpaList);
252 * Update AutomationCompositionElement.
254 * @param element the AutomationCompositionElement
256 public void updateAutomationCompositionElement(@NonNull final AutomationCompositionElement element) {
257 var jpaAcElement = acElementRepository.getReferenceById(element.getId().toString());
258 jpaAcElement.setMessage(element.getMessage());
259 jpaAcElement.setOutProperties(element.getOutProperties());
260 jpaAcElement.setOperationalState(element.getOperationalState());
261 jpaAcElement.setUseState(element.getUseState());
262 jpaAcElement.setDeployState(element.getDeployState());
263 jpaAcElement.setLockState(element.getLockState());
264 jpaAcElement.setSubState(element.getSubState());
265 jpaAcElement.setStage(element.getStage());
266 jpaAcElement.setRestarting(element.getRestarting());
268 ProviderUtils.validate(element, jpaAcElement, "AutomationCompositionElement");
269 acElementRepository.save(jpaAcElement);
273 * Delete AutomationCompositionElement.
275 * @param elementId the AutomationCompositionElement Id
277 public void deleteAutomationCompositionElement(@NonNull final UUID elementId) {
278 acElementRepository.deleteById(elementId.toString());
282 * Validate ElementIds.
284 * @param automationComposition the AutomationComposition
285 * @return the BeanValidationResult
287 public BeanValidationResult validateElementIds(final AutomationComposition automationComposition) {
288 var result = new BeanValidationResult(
289 "UUID elements " + automationComposition.getName(), automationComposition);
291 var ids = automationComposition
292 .getElements().values().stream().map(AutomationCompositionElement::getId).toList();
293 var elements = acElementRepository.findAllById(ids.stream().map(UUID::toString).toList());
294 if (automationComposition.getInstanceId() == null) {
295 for (var element : elements) {
297 element.getDescription(), element.getElementId(), ValidationStatus.INVALID, "UUID already used");
300 var instanceId = automationComposition.getInstanceId().toString();
301 for (var element : elements) {
302 if (!instanceId.equals(element.getInstanceId())) {
304 element.getDescription(), element.getElementId(), ValidationStatus.INVALID,
305 "UUID already used");