5281cb5376a7955a356a710bac5012bc13457d1d
[policy/clamp.git] /
1 /*-
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.clamp.acm.runtime.instantiation;
23
24 import java.util.UUID;
25 import javax.validation.Valid;
26 import javax.ws.rs.core.Response;
27 import javax.ws.rs.core.Response.Status;
28 import lombok.AllArgsConstructor;
29 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
30 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
31 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState;
32 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions;
33 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AcInstanceStateUpdate;
34 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse;
35 import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
36 import org.onap.policy.clamp.models.acm.persistence.provider.AcInstanceStateResolver;
37 import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
38 import org.onap.policy.clamp.models.acm.utils.AcmUtils;
39 import org.onap.policy.common.parameters.BeanValidationResult;
40 import org.onap.policy.common.parameters.ObjectValidationResult;
41 import org.onap.policy.common.parameters.ValidationStatus;
42 import org.onap.policy.models.base.PfModelRuntimeException;
43 import org.springframework.stereotype.Service;
44 import org.springframework.transaction.annotation.Transactional;
45
46 /**
47  * This class is dedicated to the Instantiation of Commissioned automation composition.
48  */
49 @Service
50 @Transactional
51 @AllArgsConstructor
52 public class AutomationCompositionInstantiationProvider {
53     private static final String DO_NOT_MATCH = " do not match with ";
54
55     private final AutomationCompositionProvider automationCompositionProvider;
56     private final AcDefinitionProvider acDefinitionProvider;
57     private final AcInstanceStateResolver acInstanceStateResolver;
58
59     /**
60      * Create automation composition.
61      *
62      * @param compositionId The UUID of the automation composition definition
63      * @param automationComposition the automation composition
64      * @return the result of the instantiation operation
65      */
66     public InstantiationResponse createAutomationComposition(UUID compositionId,
67             AutomationComposition automationComposition) {
68         if (!compositionId.equals(automationComposition.getCompositionId())) {
69             throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
70                     automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
71         }
72         var checkAutomationCompositionOpt =
73                 automationCompositionProvider.findAutomationComposition(automationComposition.getKey().asIdentifier());
74         if (checkAutomationCompositionOpt.isPresent()) {
75             throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
76                     automationComposition.getKey().asIdentifier() + " already defined");
77         }
78
79         var validationResult = validateAutomationComposition(automationComposition);
80         if (!validationResult.isValid()) {
81             throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
82         }
83         automationComposition = automationCompositionProvider.createAutomationComposition(automationComposition);
84
85         var response = new InstantiationResponse();
86         response.setInstanceId(automationComposition.getInstanceId());
87         response.setAffectedAutomationComposition(automationComposition.getKey().asIdentifier());
88
89         return response;
90     }
91
92     /**
93      * Update automation composition.
94      *
95      * @param compositionId The UUID of the automation composition definition
96      * @param automationComposition the automation composition
97      * @return the result of the update
98      */
99     public InstantiationResponse updateAutomationComposition(UUID compositionId,
100             AutomationComposition automationComposition) {
101         var instanceId = automationComposition.getInstanceId();
102         var acToUpdate = automationCompositionProvider.getAutomationComposition(instanceId);
103         if (!compositionId.equals(acToUpdate.getCompositionId())) {
104             throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
105                     automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
106         }
107         acToUpdate.setElements(automationComposition.getElements());
108         acToUpdate.setName(automationComposition.getName());
109         acToUpdate.setVersion(automationComposition.getVersion());
110         acToUpdate.setDescription(automationComposition.getDescription());
111         acToUpdate.setDerivedFrom(automationComposition.getDerivedFrom());
112         var validationResult = validateAutomationComposition(acToUpdate);
113         if (!validationResult.isValid()) {
114             throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
115         }
116         automationComposition = automationCompositionProvider.updateAutomationComposition(acToUpdate);
117
118         var response = new InstantiationResponse();
119         response.setInstanceId(instanceId);
120         response.setAffectedAutomationComposition(automationComposition.getKey().asIdentifier());
121         return response;
122     }
123
124     /**
125      * Validate AutomationComposition.
126      *
127      * @param automationComposition AutomationComposition to validate
128      * @return the result of validation
129      */
130     private BeanValidationResult validateAutomationComposition(AutomationComposition automationComposition) {
131
132         var result = new BeanValidationResult("AutomationComposition", automationComposition);
133         var acDefinitionOpt = acDefinitionProvider.findAcDefinition(automationComposition.getCompositionId());
134         if (acDefinitionOpt.isEmpty()) {
135             result.addResult(new ObjectValidationResult("ServiceTemplate", "", ValidationStatus.INVALID,
136                     "Commissioned automation composition definition not found"));
137             return result;
138         }
139         if (!AcTypeState.PRIMED.equals(acDefinitionOpt.get().getState())) {
140             result.addResult(new ObjectValidationResult("ServiceTemplate", "", ValidationStatus.INVALID,
141                     "Commissioned automation composition definition not primed"));
142             return result;
143         }
144         result.addResult(AcmUtils.validateAutomationComposition(automationComposition,
145                 acDefinitionOpt.get().getServiceTemplate()));
146
147         if (result.isValid()) {
148             for (var element : automationComposition.getElements().values()) {
149                 var name = element.getDefinition().getName();
150                 var participantId = acDefinitionOpt.get().getElementStateMap().get(name).getParticipantId();
151                 element.setParticipantId(participantId);
152             }
153         }
154
155         return result;
156     }
157
158     /**
159      * Get Automation Composition.
160      *
161      * @param compositionId The UUID of the automation composition definition
162      * @param instanceId The UUID of the automation composition instance
163      * @return the Automation Composition
164      */
165     @Transactional(readOnly = true)
166     public AutomationComposition getAutomationComposition(UUID compositionId, UUID instanceId) {
167         var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
168         if (!automationComposition.getCompositionId().equals(compositionId)) {
169             throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
170                     "Composition Id " + compositionId + DO_NOT_MATCH + automationComposition.getCompositionId());
171         }
172         return automationComposition;
173     }
174
175     /**
176      * Delete the automation composition with the given name and version.
177      *
178      * @param compositionId The UUID of the automation composition definition
179      * @param instanceId The UUID of the automation composition instance
180      * @return the result of the deletion
181      */
182     public InstantiationResponse deleteAutomationComposition(UUID compositionId, UUID instanceId) {
183         var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
184         if (!compositionId.equals(automationComposition.getCompositionId())) {
185             throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
186                     automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
187         }
188         if (!AutomationCompositionState.UNINITIALISED.equals(automationComposition.getState())) {
189             throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
190                     "Automation composition state is still " + automationComposition.getState());
191         }
192         var response = new InstantiationResponse();
193         automationComposition =
194                 automationCompositionProvider.deleteAutomationComposition(automationComposition.getInstanceId());
195         response.setInstanceId(automationComposition.getInstanceId());
196         response.setAffectedAutomationComposition(automationComposition.getKey().asIdentifier());
197         return response;
198     }
199
200     /**
201      * Get the requested automation compositions.
202      *
203      * @param name the name of the automation composition to get, null for all automation compositions
204      * @param version the version of the automation composition to get, null for all automation compositions
205      * @return the automation compositions
206      */
207     @Transactional(readOnly = true)
208     public AutomationCompositions getAutomationCompositions(UUID compositionId, String name, String version) {
209         var automationCompositions = new AutomationCompositions();
210         automationCompositions.setAutomationCompositionList(
211                 automationCompositionProvider.getAutomationCompositions(compositionId, name, version));
212
213         return automationCompositions;
214     }
215
216     /**
217      * Handle Composition Instance State.
218      *
219      * @param compositionId the compositionId
220      * @param instanceId the instanceId
221      * @param acInstanceStateUpdate the AcInstanceStateUpdate
222      */
223     public void compositionInstanceState(UUID compositionId, UUID instanceId,
224             @Valid AcInstanceStateUpdate acInstanceStateUpdate) {
225         var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
226         if (!compositionId.equals(automationComposition.getCompositionId())) {
227             throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
228                     automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
229         }
230         var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId());
231         var result = acInstanceStateResolver.resolve(acInstanceStateUpdate.getDeployOrder(),
232                 acInstanceStateUpdate.getLockOrder(), automationComposition.getDeployState(),
233                 automationComposition.getLockState());
234         switch (result) {
235             case "DEPLOY":
236                 //
237                 break;
238
239             case "UNDEPLOY":
240                 //
241                 break;
242
243             case "LOCK":
244                 //
245                 break;
246
247             case "UNLOCK":
248                 //
249                 break;
250
251             default:
252                 throw new PfModelRuntimeException(Status.BAD_REQUEST, "Not valid " + acInstanceStateUpdate);
253         }
254     }
255 }