Interface operation support for service - BE
[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 java.util.Collections;
22 import java.util.Map;
23 import java.util.Optional;
24 import java.util.UUID;
25 import org.openecomp.sdc.be.components.validation.InterfaceOperationValidation;
26 import org.openecomp.sdc.be.dao.api.ActionStatus;
27 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
28 import org.openecomp.sdc.be.model.ArtifactDefinition;
29 import org.openecomp.sdc.be.model.InterfaceDefinition;
30 import org.openecomp.sdc.be.model.Operation;
31 import org.openecomp.sdc.be.model.User;
32 import org.openecomp.sdc.be.model.jsontitan.utils.InterfaceUtils;
33 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
34 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
35 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
36 import org.openecomp.sdc.exception.ResponseFormat;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39 import org.springframework.beans.factory.annotation.Autowired;
40 import org.springframework.stereotype.Component;
41
42 @Component("interfaceOperationBusinessLogic")
43 public class InterfaceOperationBusinessLogic extends BaseBusinessLogic {
44
45     private static final Logger LOGGER = LoggerFactory.getLogger(InterfaceOperationBusinessLogic.class);
46     private static final String FAILED_TO_LOCK_COMPONENT_RESPONSE_IS = "Failed to lock component {}. Response is {}";
47     private static final String EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION = "Exception occurred during {}. Response is {}";
48     private static final String DELETE_INTERFACE_OPERATION = "deleteInterfaceOperation";
49     private static final String GET_INTERFACE_OPERATION = "getInterfaceOperation";
50     private static final String CREATE_INTERFACE_OPERATION = "createInterfaceOperation";
51     private static final String UPDATE_INTERFACE_OPERATION = "updateInterfaceOperation";
52
53     @Autowired
54     private InterfaceOperationValidation interfaceOperationValidation;
55
56     public void setInterfaceOperationValidation(InterfaceOperationValidation interfaceOperationValidation) {
57         this.interfaceOperationValidation = interfaceOperationValidation;
58     }
59
60     public Either<Operation, ResponseFormat> deleteInterfaceOperation(String componentId, String interfaceOperationToDelete, User user, boolean lock) {
61         Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither = getComponentDetails(componentId);
62         if (componentEither.isRight()){
63             return Either.right(componentEither.right().value());
64         }
65         org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value();
66         validateUserExists(user.getUserId(), DELETE_INTERFACE_OPERATION, true);
67
68         Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock, storedComponent, DELETE_INTERFACE_OPERATION);
69         if (lockResult.isRight()) {
70             return Either.right(lockResult.right().value());
71         }
72
73         try {
74             Optional<InterfaceDefinition> optionalInterface = InterfaceUtils.getInterfaceDefinitionFromToscaName(storedComponent.getInterfaces().values(), storedComponent.getName());
75             Either<InterfaceDefinition, ResponseFormat> getInterfaceEither = getInterfaceDefinition(storedComponent, optionalInterface.orElse(null));
76             if (getInterfaceEither.isRight()) {
77                 return Either.right(getInterfaceEither.right().value());
78             }
79             InterfaceDefinition interfaceDefinition = getInterfaceEither.left().value();
80
81             Either<Operation, ResponseFormat> getOperationEither = getOperationFromInterfaceDef(storedComponent, interfaceDefinition, interfaceOperationToDelete);
82             if (getOperationEither.isRight()){
83                 return Either.right(getOperationEither.right().value());
84             }
85
86             Either<Operation, StorageOperationStatus> deleteEither = interfaceOperation.deleteInterfaceOperation(componentId, interfaceDefinition, interfaceOperationToDelete);
87             if (deleteEither.isRight()){
88                 LOGGER.error("Failed to delete interface operation from component {}. Response is {}", storedComponent.getName(), deleteEither.right().value());
89                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteEither.right().value(), storedComponent.getComponentType())));
90             }
91
92             titanDao.commit();
93             return Either.left(deleteEither.left().value());
94         }
95         catch (Exception e){
96             LOGGER.error(EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION, "delete", e);
97             titanDao.rollback();
98             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_DELETED));
99         }
100         finally {
101             if (lockResult.isLeft() && lockResult.left().value()) {
102                 graphLockOperation.unlockComponent(storedComponent.getUniqueId(), NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
103             }
104         }
105     }
106
107     public Either<Operation, ResponseFormat> getInterfaceOperation(String componentId, String interfaceOperationToGet, User user, boolean lock) {
108         Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither = getComponentDetails(componentId);
109         if (componentEither.isRight()){
110             return Either.right(componentEither.right().value());
111         }
112         org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value();
113         validateUserExists(user.getUserId(), GET_INTERFACE_OPERATION, true);
114
115         Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock, storedComponent, GET_INTERFACE_OPERATION);
116         if (lockResult.isRight()) {
117             return Either.right(lockResult.right().value());
118         }
119
120         try {
121             Optional<InterfaceDefinition> optionalInterface = InterfaceUtils.getInterfaceDefinitionFromToscaName(storedComponent.getInterfaces().values(), storedComponent.getName());
122             Either<InterfaceDefinition, ResponseFormat> getInterfaceEither = getInterfaceDefinition(storedComponent, optionalInterface.orElse(null));
123             if (getInterfaceEither.isRight()) {
124                 return Either.right(getInterfaceEither.right().value());
125             }
126             InterfaceDefinition interfaceDefinition = getInterfaceEither.left().value();
127
128             Either<Operation, ResponseFormat> getOperationEither = getOperationFromInterfaceDef(storedComponent, interfaceDefinition, interfaceOperationToGet);
129             if (getOperationEither.isRight()){
130                 return Either.right(getOperationEither.right().value());
131             }
132
133             titanDao.commit();
134             return Either.left(getOperationEither.left().value());
135         }
136         catch (Exception e){
137             LOGGER.error(EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION, "get", e);
138             titanDao.rollback();
139             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, componentId));
140         }
141         finally {
142             if (lockResult.isLeft() && lockResult.left().value()) {
143                 graphLockOperation.unlockComponent(storedComponent.getUniqueId(), NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
144             }
145         }
146     }
147
148     private Either<InterfaceDefinition, ResponseFormat> getInterfaceDefinition(org.openecomp.sdc.be.model.Component component, InterfaceDefinition interfaceDef) {
149         if (interfaceDef != null){
150             return Either.left(interfaceDef);
151         } else {
152             InterfaceDefinition interfaceDefinition = new InterfaceDefinition();
153             interfaceDefinition.setToscaResourceName(InterfaceUtils.createInterfaceToscaResourceName(component.getName()));
154             Either<InterfaceDefinition, StorageOperationStatus> interfaceCreateEither = interfaceOperation.addInterface(component.getUniqueId(), interfaceDefinition);
155             if (interfaceCreateEither.isRight()){
156                 StorageOperationStatus sValue = interfaceCreateEither.right().value();
157                 LOGGER.error("Failed to get interface from component {}. Response is {}", component.getName(), sValue);
158                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(sValue, component.getComponentType()), ""));
159             }
160             return Either.left(interfaceCreateEither.left().value());
161         }
162     }
163
164     public Either<Operation, ResponseFormat> createInterfaceOperation(String componentId, Operation operation, User user, boolean lock) {
165         return createOrUpdateInterfaceOperation(componentId, operation, user, false, CREATE_INTERFACE_OPERATION, lock);
166     }
167
168     public Either<Operation, ResponseFormat> updateInterfaceOperation(String componentId, Operation operation, User user, boolean lock) {
169         return createOrUpdateInterfaceOperation(componentId, operation, user, true, UPDATE_INTERFACE_OPERATION, lock);
170     }
171
172     private Either<Operation, ResponseFormat> createOrUpdateInterfaceOperation(String componentId, Operation operation, User user, boolean isUpdate, String errorContext, boolean lock) {
173         Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither = getComponentDetails(componentId);
174         if (componentEither.isRight()){
175             return Either.right(componentEither.right().value());
176         }
177         org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value();
178         validateUserExists(user.getUserId(), errorContext, true);
179         Either<Boolean, ResponseFormat> interfaceOperationValidationResponseEither = interfaceOperationValidation
180             .validateInterfaceOperations(Collections.singletonList(operation), storedComponent, isUpdate);
181         if(interfaceOperationValidationResponseEither.isRight()) {
182             return      Either.right(interfaceOperationValidationResponseEither.right().value());
183         }
184
185         Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock, storedComponent, errorContext);
186         if (lockResult.isRight()) {
187             return Either.right(lockResult.right().value());
188         }
189
190         try {
191             Optional<InterfaceDefinition> optionalInterface = InterfaceUtils.getInterfaceDefinitionFromToscaName(storedComponent.getInterfaces().values(), storedComponent.getName());
192             Either<InterfaceDefinition, ResponseFormat> getInterfaceEither = getInterfaceDefinition(storedComponent, optionalInterface.orElse(null));
193             if (getInterfaceEither.isRight()) {
194                 return Either.right(getInterfaceEither.right().value());
195             }
196             InterfaceDefinition interfaceDefinition = getInterfaceEither.left().value();
197
198             Either<Operation, StorageOperationStatus> result;
199             if(!isUpdate){
200                 initNewOperation(operation);
201                 result = interfaceOperation.addInterfaceOperation(componentId, interfaceDefinition, operation);
202             }
203             else {
204                 Either<Operation, ResponseFormat> getOperationEither = getOperationFromInterfaceDef(storedComponent, interfaceDefinition, operation.getUniqueId());
205                 if (getOperationEither.isRight()){
206                     return Either.right(getOperationEither.right().value());
207                 }
208                 operation.setImplementation(getOperationEither.left().value().getImplementation());
209                 result = interfaceOperation.updateInterfaceOperation(componentId, interfaceDefinition, operation);
210             }
211
212             if (result.isRight()) {
213                 titanDao.rollback();
214                 LOGGER.debug("Failed to addOrUpdate interface operation on component {}. Response is {}", storedComponent.getName(), result.right().value());
215                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(result.right().value(), storedComponent.getComponentType())));
216             }
217
218             titanDao.commit();
219             return Either.left(result.left().value());
220         }
221         catch (Exception e) {
222             titanDao.rollback();
223             LOGGER.error(EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION, "addOrUpdate", e);
224             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
225         }
226         finally {
227             if (lockResult.isLeft() && lockResult.left().value()) {
228                 graphLockOperation.unlockComponent(storedComponent.getUniqueId(), NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
229             }
230         }
231     }
232
233     private Either<org.openecomp.sdc.be.model.Component, ResponseFormat> getComponentDetails(String componentId){
234         Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
235         if (componentStorageOperationStatusEither.isRight()) {
236             StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
237             LOGGER.error("Failed to fetch component information by component id {}, Response is {}", componentId, errorStatus);
238             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
239         }
240         return Either.left(componentStorageOperationStatusEither.left().value());
241     }
242
243     private Either<Operation, ResponseFormat> getOperationFromInterfaceDef(
244         org.openecomp.sdc.be.model.Component component, InterfaceDefinition interfaceDefinition, String operationToFetch) {
245         Optional<Map.Entry<String, Operation>> operationMap = interfaceDefinition.getOperationsMap().entrySet().stream()
246             .filter(entry -> entry.getValue().getUniqueId().equals(operationToFetch)).findAny();
247         if (!operationMap.isPresent()) {
248             LOGGER.error("Failed to get interface operation from component {}. Response is {}", component.getUniqueId(), ActionStatus.INTERFACE_OPERATION_NOT_FOUND);
249             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, component.getUniqueId()));
250         }
251         return Either.left(operationMap.get().getValue());
252     }
253
254     private void initNewOperation(Operation operation){
255         ArtifactDefinition artifactDefinition = new ArtifactDefinition();
256         String artifactUUID = UUID.randomUUID().toString();
257         artifactDefinition.setArtifactUUID(artifactUUID);
258         artifactDefinition.setUniqueId(artifactUUID);
259         artifactDefinition.setArtifactType(ArtifactTypeEnum.PLAN.getType());
260         artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.LIFE_CYCLE);
261         operation.setUniqueId(UUID.randomUUID().toString());
262         operation.setImplementation(artifactDefinition);
263     }
264
265     private Either<Boolean, ResponseFormat> lockComponentResult(boolean lock, org.openecomp.sdc.be.model.Component component, String action){
266         if (lock) {
267             Either<Boolean, ResponseFormat> lockResult = lockComponent(component.getUniqueId(), component, action);
268             if (lockResult.isRight()) {
269                 LOGGER.debug(FAILED_TO_LOCK_COMPONENT_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
270                 titanDao.rollback();
271                 return Either.right(lockResult.right().value());
272             }
273         }
274         return Either.left(true);
275     }
276 }