Revert "Interface operation feature enhancements"
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / InterfaceOperationBusinessLogic.java
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 package org.openecomp.sdc.be.components.impl;
19
20 import fj.data.Either;
21 import org.openecomp.sdc.be.components.validation.InterfaceOperationValidation;
22 import org.openecomp.sdc.be.dao.api.ActionStatus;
23 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
24 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
25 import org.openecomp.sdc.be.model.ArtifactDefinition;
26 import org.openecomp.sdc.be.model.InterfaceDefinition;
27 import org.openecomp.sdc.be.model.Operation;
28 import org.openecomp.sdc.be.model.User;
29 import org.openecomp.sdc.be.model.jsontitan.utils.InterfaceUtils;
30 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
31 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
32 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
33 import org.openecomp.sdc.exception.ResponseFormat;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36 import org.springframework.beans.factory.annotation.Autowired;
37 import org.springframework.stereotype.Component;
38
39 import java.util.Collection;
40 import java.util.Collections;
41 import java.util.Map;
42 import java.util.Optional;
43 import java.util.UUID;
44 import java.util.stream.Collectors;
45
46 @Component("interfaceOperationBusinessLogic")
47 public class InterfaceOperationBusinessLogic extends BaseBusinessLogic {
48
49     private static final Logger LOGGER = LoggerFactory.getLogger(InterfaceOperationBusinessLogic.class);
50     private static final String FAILED_TO_LOCK_COMPONENT_RESPONSE_IS = "Failed to lock component {}. Response is {}";
51     private static final String EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION = "Exception occurred during {}. Response is {}";
52     private static final String DELETE_INTERFACE_OPERATION = "deleteInterfaceOperation";
53     private static final String GET_INTERFACE_OPERATION = "getInterfaceOperation";
54     private static final String CREATE_INTERFACE_OPERATION = "createInterfaceOperation";
55     private static final String UPDATE_INTERFACE_OPERATION = "updateInterfaceOperation";
56
57     @Autowired
58     private InterfaceOperationValidation interfaceOperationValidation;
59
60     public void setInterfaceOperationValidation(InterfaceOperationValidation interfaceOperationValidation) {
61         this.interfaceOperationValidation = interfaceOperationValidation;
62     }
63
64     public Either<Operation, ResponseFormat> deleteInterfaceOperation(String componentId, String interfaceOperationToDelete, User user, boolean lock) {
65         Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither = getComponentDetails(componentId);
66         if (componentEither.isRight()){
67             return Either.right(componentEither.right().value());
68         }
69         org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value();
70         validateUserExists(user.getUserId(), DELETE_INTERFACE_OPERATION, true);
71
72         Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock, storedComponent, DELETE_INTERFACE_OPERATION);
73         if (lockResult.isRight()) {
74             return Either.right(lockResult.right().value());
75         }
76
77         try {
78             Optional<InterfaceDefinition> optionalInterface = InterfaceUtils.getInterfaceDefinitionFromToscaName(storedComponent.getInterfaces().values(), storedComponent.getName());
79             Either<InterfaceDefinition, ResponseFormat> getInterfaceEither = getInterfaceDefinition(storedComponent, optionalInterface.orElse(null));
80             if (getInterfaceEither.isRight()) {
81                 return Either.right(getInterfaceEither.right().value());
82             }
83             InterfaceDefinition interfaceDefinition = getInterfaceEither.left().value();
84
85             Either<Operation, ResponseFormat> getOperationEither = getOperationFromInterfaceDef(storedComponent, interfaceDefinition, interfaceOperationToDelete);
86             if (getOperationEither.isRight()){
87                 return Either.right(getOperationEither.right().value());
88             }
89
90             Either<Operation, StorageOperationStatus> deleteEither = interfaceOperation.deleteInterfaceOperation(componentId, interfaceDefinition, interfaceOperationToDelete);
91             if (deleteEither.isRight()){
92                 LOGGER.error("Failed to delete interface operation from component {}. Response is {}", storedComponent.getName(), deleteEither.right().value());
93                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteEither.right().value(), storedComponent.getComponentType())));
94             }
95
96             titanDao.commit();
97             return Either.left(deleteEither.left().value());
98         }
99         catch (Exception e){
100             LOGGER.error(EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION, "delete", e);
101             titanDao.rollback();
102             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_DELETED));
103         }
104         finally {
105             if (lockResult.isLeft() && lockResult.left().value()) {
106                 graphLockOperation.unlockComponent(storedComponent.getUniqueId(), NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
107             }
108         }
109     }
110
111     public Either<Operation, ResponseFormat> getInterfaceOperation(String componentId, String interfaceOperationToGet, User user, boolean lock) {
112         Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither = getComponentDetails(componentId);
113         if (componentEither.isRight()){
114             return Either.right(componentEither.right().value());
115         }
116         org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value();
117         validateUserExists(user.getUserId(), GET_INTERFACE_OPERATION, true);
118
119         Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock, storedComponent, GET_INTERFACE_OPERATION);
120         if (lockResult.isRight()) {
121             return Either.right(lockResult.right().value());
122         }
123
124         try {
125             Optional<InterfaceDefinition> optionalInterface = InterfaceUtils.getInterfaceDefinitionFromToscaName(storedComponent.getInterfaces().values(), storedComponent.getName());
126             Either<InterfaceDefinition, ResponseFormat> getInterfaceEither = getInterfaceDefinition(storedComponent, optionalInterface.orElse(null));
127             if (getInterfaceEither.isRight()) {
128                 return Either.right(getInterfaceEither.right().value());
129             }
130             InterfaceDefinition interfaceDefinition = getInterfaceEither.left().value();
131
132             Either<Operation, ResponseFormat> getOperationEither = getOperationFromInterfaceDef(storedComponent, interfaceDefinition, interfaceOperationToGet);
133             if (getOperationEither.isRight()){
134                 return Either.right(getOperationEither.right().value());
135             }
136
137             titanDao.commit();
138             return Either.left(getOperationEither.left().value());
139         }
140         catch (Exception e){
141             LOGGER.error(EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION, "get", e);
142             titanDao.rollback();
143             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, componentId));
144         }
145         finally {
146             if (lockResult.isLeft() && lockResult.left().value()) {
147                 graphLockOperation.unlockComponent(storedComponent.getUniqueId(), NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
148             }
149         }
150     }
151
152     private Either<InterfaceDefinition, ResponseFormat> getInterfaceDefinition(org.openecomp.sdc.be.model.Component component, InterfaceDefinition interfaceDef) {
153         if (interfaceDef != null){
154             return Either.left(interfaceDef);
155         } else {
156             InterfaceDefinition interfaceDefinition = new InterfaceDefinition();
157             interfaceDefinition.setToscaResourceName(InterfaceUtils.createInterfaceToscaResourceName(component.getName()));
158             Either<InterfaceDefinition, StorageOperationStatus> interfaceCreateEither = interfaceOperation.addInterface(component.getUniqueId(), interfaceDefinition);
159             if (interfaceCreateEither.isRight()){
160                 StorageOperationStatus sValue = interfaceCreateEither.right().value();
161                 LOGGER.error("Failed to get interface from component {}. Response is {}", component.getName(), sValue);
162                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(sValue, component.getComponentType()), ""));
163             }
164             return Either.left(interfaceCreateEither.left().value());
165         }
166     }
167
168     public Either<Operation, ResponseFormat> createInterfaceOperation(String componentId, Operation operation, User user, boolean lock) {
169         return createOrUpdateInterfaceOperation(componentId, operation, user, false, CREATE_INTERFACE_OPERATION, lock);
170     }
171
172     public Either<Operation, ResponseFormat> updateInterfaceOperation(String componentId, Operation operation, User user, boolean lock) {
173         return createOrUpdateInterfaceOperation(componentId, operation, user, true, UPDATE_INTERFACE_OPERATION, lock);
174     }
175
176     private Either<Operation, ResponseFormat> createOrUpdateInterfaceOperation(String componentId, Operation operation, User user, boolean isUpdate, String errorContext, boolean lock) {
177         Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither = getComponentDetails(componentId);
178         if (componentEither.isRight()){
179             return Either.right(componentEither.right().value());
180         }
181         org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value();
182         validateUserExists(user.getUserId(), errorContext, true);
183         Either<Boolean, ResponseFormat> interfaceOperationValidationResponseEither = interfaceOperationValidation
184             .validateInterfaceOperations(Collections.singletonList(operation), storedComponent, isUpdate);
185         if(interfaceOperationValidationResponseEither.isRight()) {
186             return      Either.right(interfaceOperationValidationResponseEither.right().value());
187         }
188
189         Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock, storedComponent, errorContext);
190         if (lockResult.isRight()) {
191             return Either.right(lockResult.right().value());
192         }
193
194         try {
195             Optional<InterfaceDefinition> optionalInterface = InterfaceUtils.getInterfaceDefinitionFromToscaName(storedComponent.getInterfaces().values(), storedComponent.getName());
196             Either<InterfaceDefinition, ResponseFormat> getInterfaceEither = getInterfaceDefinition(storedComponent, optionalInterface.orElse(null));
197             if (getInterfaceEither.isRight()) {
198                 return Either.right(getInterfaceEither.right().value());
199             }
200             InterfaceDefinition interfaceDefinition = getInterfaceEither.left().value();
201
202             Either<Operation, StorageOperationStatus> result;
203             if(!isUpdate){
204                 initNewOperation(operation);
205                 result = interfaceOperation.addInterfaceOperation(componentId, interfaceDefinition, operation);
206             }
207             else {
208                 Either<Operation, ResponseFormat> getOperationEither = getOperationFromInterfaceDef(storedComponent, interfaceDefinition, operation.getUniqueId());
209                 if (getOperationEither.isRight()){
210                     return Either.right(getOperationEither.right().value());
211                 }
212                 updateExistingOperation(operation, getOperationEither.left().value().getImplementation().getArtifactUUID());
213                 result = interfaceOperation.updateInterfaceOperation(componentId, interfaceDefinition, operation);
214             }
215
216             if (result.isRight()) {
217                 titanDao.rollback();
218                 LOGGER.debug("Failed to addOrUpdate interface operation on component {}. Response is {}", storedComponent.getName(), result.right().value());
219                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(result.right().value(), storedComponent.getComponentType())));
220             }
221
222             titanDao.commit();
223             return Either.left(result.left().value());
224         }
225         catch (Exception e) {
226             titanDao.rollback();
227             LOGGER.error(EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION, "addOrUpdate", e);
228             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
229         }
230         finally {
231             if (lockResult.isLeft() && lockResult.left().value()) {
232                 graphLockOperation.unlockComponent(storedComponent.getUniqueId(), NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
233             }
234         }
235     }
236
237     private Either<org.openecomp.sdc.be.model.Component, ResponseFormat> getComponentDetails(String componentId){
238         Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
239         if (componentStorageOperationStatusEither.isRight()) {
240             StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
241             LOGGER.error("Failed to fetch component information by component id {}, Response is {}", componentId, errorStatus);
242             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
243         }
244         return Either.left(componentStorageOperationStatusEither.left().value());
245     }
246
247     private Either<Operation, ResponseFormat> getOperationFromInterfaceDef(
248         org.openecomp.sdc.be.model.Component component, InterfaceDefinition interfaceDefinition, String operationToFetch) {
249         Optional<Map.Entry<String, Operation>> operationMap = interfaceDefinition.getOperationsMap().entrySet().stream()
250             .filter(entry -> entry.getValue().getUniqueId().equals(operationToFetch)).findAny();
251         if (!operationMap.isPresent()) {
252             LOGGER.error("Failed to get interface operation from component {}. Response is {}", component.getUniqueId(), ActionStatus.INTERFACE_OPERATION_NOT_FOUND);
253             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, component.getUniqueId()));
254         }
255         return Either.left(operationMap.get().getValue());
256     }
257
258     private void initNewOperation(Operation operation){
259         ArtifactDefinition artifactDefinition = new ArtifactDefinition();
260         String artifactUUID = UUID.randomUUID().toString();
261         artifactDefinition.setArtifactUUID(artifactUUID);
262         artifactDefinition.setUniqueId(artifactUUID);
263         artifactDefinition.setArtifactType(ArtifactTypeEnum.WORKFLOW.getType());
264         artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
265         operation.setUniqueId(UUID.randomUUID().toString());
266         operation.setImplementation(artifactDefinition);
267     }
268
269     private void updateExistingOperation(Operation operation, String artifactUUID){
270         ArtifactDefinition artifactDefinition = new ArtifactDefinition();
271         artifactDefinition.setArtifactUUID(artifactUUID);
272         artifactDefinition.setUniqueId(artifactUUID);
273         artifactDefinition.setArtifactType(ArtifactTypeEnum.WORKFLOW.getType());
274         artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
275         operation.setImplementation(artifactDefinition);
276     }
277
278     private Either<Boolean, ResponseFormat> lockComponentResult(boolean lock, org.openecomp.sdc.be.model.Component component, String action){
279         if (lock) {
280             Either<Boolean, ResponseFormat> lockResult = lockComponent(component.getUniqueId(), component, action);
281             if (lockResult.isRight()) {
282                 LOGGER.debug(FAILED_TO_LOCK_COMPONENT_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
283                 titanDao.rollback();
284                 return Either.right(lockResult.right().value());
285             }
286         }
287         return Either.left(true);
288     }
289
290     public Either<Boolean, ResponseFormat> validateComponentNameAndUpdateInterfaces(org.openecomp.sdc.be.model.Component oldComponent,
291                                                                                     org.openecomp.sdc.be.model.Component newComponent) {
292         if(!oldComponent.getName().equals(newComponent.getName()) ) {
293             Collection<InterfaceDefinition> interfaceDefinitionListFromToscaName = InterfaceUtils
294                     .getInterfaceDefinitionListFromToscaName(oldComponent.getInterfaces().values(),
295                             oldComponent.getName());
296             for (InterfaceDefinition interfaceDefinition : interfaceDefinitionListFromToscaName) {
297
298                 Either<InterfaceDefinition, ResponseFormat> interfaceDefinitionResponseEither = updateInterfaceDefinition(oldComponent,
299                                                                     newComponent, interfaceDefinition);
300                 if(interfaceDefinitionResponseEither.isRight()) {
301                     return Either.right(interfaceDefinitionResponseEither.right().value());
302                 }
303             }
304         }
305         return  Either.left(Boolean.TRUE);
306     }
307     private Either<InterfaceDefinition, ResponseFormat > updateInterfaceDefinition(org.openecomp.sdc.be.model.Component oldComponent,
308                                         org.openecomp.sdc.be.model.Component newComponent,
309                                         InterfaceDefinition interfaceDefinition) {
310                         InterfaceUtils.createInterfaceToscaResourceName(newComponent.getName());
311                 interfaceDefinition.setToscaResourceName(InterfaceUtils
312                         .createInterfaceToscaResourceName(newComponent.getName()));
313         try {
314             Either<InterfaceDefinition, StorageOperationStatus> interfaceUpdate = interfaceOperation
315                     .updateInterface(oldComponent.getUniqueId(), interfaceDefinition);
316             if (interfaceUpdate.isRight()) {
317                 LOGGER.error("Failed to Update interface {}. Response is {}. ", newComponent.getName(), interfaceUpdate.right().value());
318                 titanDao.rollback();
319                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(interfaceUpdate.right().value(), ComponentTypeEnum.RESOURCE)));
320             }
321         } catch (Exception e) {
322             LOGGER.error("Exception occurred during update interface toscaResourceName  : {}", e);
323             titanDao.rollback();
324             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
325         }
326         return Either.left( interfaceDefinition);
327     }
328
329     public Either<Map<String, InterfaceDefinition>, ResponseFormat> getAllInterfaceLifecycleTypes() {
330
331         Either<Map<String, InterfaceDefinition>, StorageOperationStatus> interfaceLifecycleTypes = interfaceLifecycleOperation.getAllInterfaceLifecycleTypes();
332         if(interfaceLifecycleTypes.isRight()) {
333             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_LIFECYCLE_TYPES_NOT_FOUND));
334         }
335         interfaceLifecycleTypes.left().value().values().stream().forEach(
336             id -> id.setOperations(id.getOperations().keySet().stream().collect(Collectors.toMap(key -> key.replaceFirst(id.getUniqueId()+".",""), i -> id.getOperations().get(i)))));
337
338         return Either.left(interfaceLifecycleTypes.left().value());
339     }
340 }