Support setting interfaces on instances
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ComponentInterfaceOperationBusinessLogic.java
1 /*
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  *  Copyright (C) 2021 Nordix Foundation. 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
10  *
11  *        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.zone-instance.component.ts
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.openecomp.sdc.be.components.impl;
23
24 import static org.openecomp.sdc.be.components.impl.ImportUtils.Constants.QUOTE;
25
26 import com.google.common.reflect.TypeToken;
27 import com.google.gson.Gson;
28 import com.google.gson.GsonBuilder;
29 import fj.data.Either;
30 import java.lang.reflect.Type;
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Optional;
37 import java.util.UUID;
38 import java.util.stream.Collectors;
39 import org.apache.commons.collections.CollectionUtils;
40 import org.apache.commons.collections.ListUtils;
41 import org.apache.commons.collections.MapUtils;
42 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
43 import org.openecomp.sdc.be.components.validation.ComponentValidations;
44 import org.openecomp.sdc.be.dao.api.ActionStatus;
45 import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil;
46 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
47 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
48 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
49 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
50 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
51 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
52 import org.openecomp.sdc.be.model.ArtifactTypeDefinition;
53 import org.openecomp.sdc.be.model.Component;
54 import org.openecomp.sdc.be.model.ComponentInstance;
55 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
56 import org.openecomp.sdc.be.model.ComponentParametersView;
57 import org.openecomp.sdc.be.model.InterfaceDefinition;
58 import org.openecomp.sdc.be.model.PropertyConstraint;
59 import org.openecomp.sdc.be.model.PropertyDefinition;
60 import org.openecomp.sdc.be.model.User;
61 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
62 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
63 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
64 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
65 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
66 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
67 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
68 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
69 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
70 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
71 import org.openecomp.sdc.be.tosca.utils.OperationArtifactUtil;
72 import org.openecomp.sdc.be.user.Role;
73 import org.openecomp.sdc.common.datastructure.Wrapper;
74 import org.openecomp.sdc.exception.ResponseFormat;
75 import org.slf4j.Logger;
76 import org.slf4j.LoggerFactory;
77 import org.springframework.beans.factory.annotation.Autowired;
78
79 @org.springframework.stereotype.Component("componentInterfaceOperationBusinessLogic")
80 public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic {
81
82     private static final Logger LOGGER = LoggerFactory.getLogger(ComponentInterfaceOperationBusinessLogic.class);
83     private static final String UPDATE_INTERFACE_OPERATION_ON_COMPONENT_INSTANCE =
84         "Update Interface Operation on Component instance";
85     private static final String EXCEPTION_OCCURRED_WHEN_UPDATING_COMPONENT_INSTANCE_INTERFACES =
86         "Exception occurred when updating Component Instance Interfaces {}";
87     private final ComponentValidations componentValidations;
88     private final PropertyBusinessLogic propertyBusinessLogic;
89     private final ArtifactTypeBusinessLogic artifactTypeBusinessLogic;
90
91     @Autowired
92     public ComponentInterfaceOperationBusinessLogic(final IElementOperation elementDao, final IGroupOperation groupOperation,
93                                                     final IGroupInstanceOperation groupInstanceOperation,
94                                                     final IGroupTypeOperation groupTypeOperation, final InterfaceOperation interfaceOperation,
95                                                     final InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
96                                                     final ArtifactsOperations artifactToscaOperation,
97                                                     final ComponentValidations componentValidations,
98                                                     final PropertyBusinessLogic propertyBusinessLogic,
99                                                     final ArtifactTypeBusinessLogic artifactTypeBusinessLogic) {
100         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
101             artifactToscaOperation);
102         this.componentValidations = componentValidations;
103         this.propertyBusinessLogic = propertyBusinessLogic;
104         this.artifactTypeBusinessLogic = artifactTypeBusinessLogic;
105     }
106
107     public Optional<ComponentInstance> updateComponentInstanceInterfaceOperation(final String componentId, final String componentInstanceId,
108                                                                                  final InterfaceDefinition interfaceDefinition,
109                                                                                  final ComponentTypeEnum componentTypeEnum,
110                                                                                  final Wrapper<ResponseFormat> errorWrapper, final boolean shouldLock)
111         throws BusinessLogicException {
112         final Component component = getComponent(componentId);
113         final Optional<ComponentInstance> componentInstanceOptional = componentValidations.getComponentInstance(component, componentInstanceId);
114         ResponseFormat responseFormat;
115         if (componentInstanceOptional.isEmpty()) {
116             responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND);
117             LOGGER.debug("Failed to found component instance with id {}, error: {}", componentInstanceId, responseFormat);
118             errorWrapper.setInnerElement(responseFormat);
119             return Optional.empty();
120         }
121         Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaceMap = component.getComponentInstancesInterfaces();
122         if (MapUtils.isEmpty(componentInstancesInterfaceMap)) {
123             componentInstancesInterfaceMap = new HashMap<>();
124             component.setComponentInstancesInterfaces(componentInstancesInterfaceMap);
125         }
126         final List<ComponentInstanceInterface> componentInstanceInterfaceList = componentInstancesInterfaceMap.get(componentInstanceId);
127         if (CollectionUtils.isEmpty(componentInstanceInterfaceList)) {
128             responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND);
129             LOGGER.debug("Failed to found component instance with id {}, error: {}", componentInstanceId, responseFormat);
130             errorWrapper.setInnerElement(responseFormat);
131             return Optional.empty();
132         }
133         final Optional<OperationDataDefinition> optionalOperationDataDefinition = interfaceDefinition.getOperations().values().stream().findFirst();
134         if (optionalOperationDataDefinition.isEmpty()) {
135             responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND);
136             LOGGER.debug("Failed to found interface operation on component instance with id {}, error: {}", componentInstanceId, responseFormat);
137             errorWrapper.setInnerElement(responseFormat);
138             return Optional.empty();
139         }
140         final OperationDataDefinition updatedOperationDataDefinition = optionalOperationDataDefinition.get();
141         final Optional<ComponentInstanceInterface> optionalComponentInstanceInterface = componentInstanceInterfaceList.stream().filter(
142                 ci -> ci.getOperations().values().stream().anyMatch(
143                     operationDataDefinition -> operationDataDefinition.getUniqueId().equalsIgnoreCase(updatedOperationDataDefinition.getUniqueId())))
144             .findFirst();
145         if (optionalComponentInstanceInterface.isEmpty()) {
146             responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT);
147             LOGGER
148                 .debug("Failed to found ComponentInstanceInterface on component instance with id {}, error: {}", componentInstanceId, responseFormat);
149             errorWrapper.setInnerElement(responseFormat);
150             return Optional.empty();
151         }
152
153         final String model = propertyBusinessLogic.getComponentModelByComponentId(componentId);
154         PropertyValueConstraintValidationUtil constraintValidatorUtil = new PropertyValueConstraintValidationUtil();
155         Either<Boolean, ResponseFormat> constraintValidatorResponse =
156             validateOperationInputConstraints(updatedOperationDataDefinition, constraintValidatorUtil, model);
157         if (!isConstraintsValidationSucceed(constraintValidatorResponse, errorWrapper, updatedOperationDataDefinition)) {
158             return Optional.empty();
159         }
160         constraintValidatorResponse = validateOperationArtifactPropertyConstraints(
161             updatedOperationDataDefinition, constraintValidatorUtil, model);
162         if (!isConstraintsValidationSucceed(constraintValidatorResponse, errorWrapper, updatedOperationDataDefinition)) {
163             return Optional.empty();
164         }
165
166         updateOperationDefinitionImplementation(updatedOperationDataDefinition);
167         optionalComponentInstanceInterface.get().getOperations().replace(updatedOperationDataDefinition.getName(), updatedOperationDataDefinition);
168         boolean wasLocked = false;
169         try {
170             if (shouldLock) {
171                 lockComponent(componentId, component, UPDATE_INTERFACE_OPERATION_ON_COMPONENT_INSTANCE);
172                 wasLocked = true;
173             }
174             final StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceInterfaces(component, componentInstanceId);
175             if (status != StorageOperationStatus.OK) {
176                 janusGraphDao.rollback();
177                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
178                 LOGGER.error(EXCEPTION_OCCURRED_WHEN_UPDATING_COMPONENT_INSTANCE_INTERFACES, responseFormat);
179                 errorWrapper.setInnerElement(responseFormat);
180                 return Optional.empty();
181             }
182             final ComponentParametersView componentFilter = new ComponentParametersView();
183             componentFilter.disableAll();
184             componentFilter.setIgnoreUsers(false);
185             componentFilter.setIgnoreComponentInstances(false);
186             componentFilter.setIgnoreInterfaces(false);
187             componentFilter.setIgnoreComponentInstancesInterfaces(false);
188             final Either<Component, StorageOperationStatus> operationStatusEither = toscaOperationFacade
189                 .updateComponentInstanceMetadataOfTopologyTemplate(component, componentFilter);
190             if (operationStatusEither.isRight()) {
191                 janusGraphDao.rollback();
192                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
193                 LOGGER.error("Exception occurred when updating Component Instance Topology template {}", responseFormat);
194                 errorWrapper.setInnerElement(responseFormat);
195                 return Optional.empty();
196             }
197             janusGraphDao.commit();
198         } catch (final Exception e) {
199             janusGraphDao.rollback();
200             LOGGER.error("Exception occurred when updating Interface Operation on Component Instance: {}", e.getMessage(), e);
201             responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
202             errorWrapper.setInnerElement(responseFormat);
203             throw new BusinessLogicException(responseFormat);
204         } finally {
205             if (wasLocked) {
206                 unlockComponent(component.getUniqueId(), componentTypeEnum);
207             }
208         }
209         return componentInstanceOptional;
210     }
211
212     private Either<Boolean, ResponseFormat> validateOperationInputConstraints(
213         OperationDataDefinition operationDataDefinition, PropertyValueConstraintValidationUtil constraintValidatorUtil, String model) {
214         return constraintValidatorUtil
215             .validatePropertyConstraints(convertOperationInputsToPropertyDefinitions(operationDataDefinition), applicationDataTypeCache,
216                 model);
217     }
218
219     private Either<Boolean, ResponseFormat> validateOperationArtifactPropertyConstraints(
220         OperationDataDefinition operationDataDefinition, PropertyValueConstraintValidationUtil constraintValidatorUtil, String model) {
221         return constraintValidatorUtil
222             .validatePropertyConstraints(convertOperationArtifactPropsToPropertyDefinitions(operationDataDefinition, model), applicationDataTypeCache,
223                 model);
224     }
225
226     private boolean isConstraintsValidationSucceed(Either<Boolean, ResponseFormat> constraintValidatorResponse,
227                                                    Wrapper<ResponseFormat> errorWrapper,
228                                                    OperationDataDefinition updatedOperationDataDefinition) {
229         if (constraintValidatorResponse.isRight()) {
230             ResponseFormat responseFormat = constraintValidatorResponse.right().value();
231             LOGGER.error("Failed constraints validation on inputs for interface operation: {} - {}",
232                 updatedOperationDataDefinition.getName(),
233                 constraintValidatorResponse.right().value());
234             errorWrapper.setInnerElement(responseFormat);
235             return false;
236         }
237         return true;
238     }
239
240     public Optional<Component> updateResourceInterfaceOperation(final String componentId,
241                                                                 final String user,
242                                                                 final InterfaceDefinition interfaceDefinition,
243                                                                 final ComponentTypeEnum componentTypeEnum,
244                                                                 final Wrapper<ResponseFormat> errorWrapper,
245                                                                 final boolean shouldLock) throws BusinessLogicException {
246         final var component = getComponent(componentId);
247         validateCanWorkOnComponent(component, user);
248         ResponseFormat responseFormat;
249
250         Map<String, InterfaceDefinition> componentInterfaceMap = component.getInterfaces();
251         final String interfaceDefinitionType = interfaceDefinition.getType();
252         if (MapUtils.isEmpty(componentInterfaceMap)) {
253             componentInterfaceMap = new HashMap<>();
254             componentInterfaceMap.put(interfaceDefinitionType, interfaceDefinition);
255             component.setInterfaces(componentInterfaceMap);
256         } else {
257             InterfaceDefinition componentInterfaceDefinition = componentInterfaceMap.get(interfaceDefinitionType);
258             if (componentInterfaceDefinition == null) {
259                 componentInterfaceDefinition = interfaceDefinition;
260                 componentInterfaceMap.put(interfaceDefinitionType, interfaceDefinition);
261             }
262
263             final Map<String, OperationDataDefinition> interfaceDefinitionOperations = interfaceDefinition.getOperations();
264             final Optional<OperationDataDefinition> optionalOperationDataDefinition = interfaceDefinitionOperations.values().stream().findFirst();
265             if (optionalOperationDataDefinition.isEmpty()) {
266                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND);
267                 LOGGER.debug("Failed to found interface operation on provided InterfaceDefinition {}, error: {}",
268                     interfaceDefinitionType, responseFormat);
269                 errorWrapper.setInnerElement(responseFormat);
270                 return Optional.empty();
271             }
272             final var updatedOperationDataDefinition = optionalOperationDataDefinition.get();
273             updateOperationDefinitionImplementation(updatedOperationDataDefinition);
274             Map<String, OperationDataDefinition> componentOperationDataDefinitionMap = componentInterfaceDefinition.getOperations();
275             if (MapUtils.isEmpty(componentOperationDataDefinitionMap)) {
276                 componentOperationDataDefinitionMap = new HashMap<>();
277                 componentInterfaceDefinition.setOperations(componentOperationDataDefinitionMap);
278             }
279             componentOperationDataDefinitionMap.replace(updatedOperationDataDefinition.getName(), updatedOperationDataDefinition);
280         }
281         boolean wasLocked = false;
282         try {
283             if (shouldLock) {
284                 lockComponent(componentId, component, UPDATE_INTERFACE_OPERATION_ON_COMPONENT_INSTANCE);
285                 wasLocked = true;
286             }
287             final StorageOperationStatus status = toscaOperationFacade.updateComponentInterfaces(component, interfaceDefinitionType);
288             if (status != StorageOperationStatus.OK) {
289                 janusGraphDao.rollback();
290                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
291                 LOGGER.error(EXCEPTION_OCCURRED_WHEN_UPDATING_COMPONENT_INSTANCE_INTERFACES, responseFormat);
292                 errorWrapper.setInnerElement(responseFormat);
293                 return Optional.empty();
294             }
295             janusGraphDao.commit();
296         } catch (final Exception e) {
297             janusGraphDao.rollback();
298             LOGGER.error("Exception occurred when updating Interface Operation on Component Instance: ", e);
299             responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
300             errorWrapper.setInnerElement(responseFormat);
301             throw new BusinessLogicException(responseFormat);
302         } finally {
303             if (wasLocked) {
304                 unlockComponent(component.getUniqueId(), componentTypeEnum);
305             }
306         }
307         return Optional.of(component);
308     }
309
310     public Optional<ComponentInstance> createComponentInstanceInterfaceOperation(String componentId, String componentInstanceId,
311                                                                                  InterfaceDefinition interfaceDefinition,
312                                                                                  ComponentTypeEnum componentTypeEnum,
313                                                                                  Wrapper<ResponseFormat> errorWrapper, final boolean shouldLock)
314         throws BusinessLogicException {
315         ResponseFormat responseFormat;
316         final Component component = getComponent(componentId);
317         final Optional<ComponentInstance> componentInstanceOptional = componentValidations.getComponentInstance(component, componentInstanceId);
318         if (componentInstanceOptional.isEmpty()) {
319             responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND);
320             LOGGER.debug("Failed to find component instance with id {}, error: {}", componentInstanceId, responseFormat);
321             errorWrapper.setInnerElement(responseFormat);
322             return Optional.empty();
323         }
324         Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaceMap = component.getComponentInstancesInterfaces();
325         if (MapUtils.isEmpty(componentInstancesInterfaceMap)) {
326             componentInstancesInterfaceMap = new HashMap<>();
327             component.setComponentInstancesInterfaces(componentInstancesInterfaceMap);
328         }
329         final String interfaceKey = interfaceDefinition.getType();
330         interfaceDefinition.setUniqueId(interfaceKey);
331         interfaceDefinition.setToscaResourceName(interfaceKey);
332         interfaceDefinition.setUserCreated(true);
333
334         final Optional<OperationDataDefinition> optionalOperationDataDefinition = interfaceDefinition.getOperations().values().stream().findFirst();
335         if (optionalOperationDataDefinition.isEmpty()) {
336             responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, interfaceKey);
337             LOGGER.debug("Failed to find interface operation on interface being added {}, error: {}", interfaceKey, responseFormat);
338             errorWrapper.setInnerElement(responseFormat);
339             return Optional.empty();
340         }
341
342         final OperationDataDefinition updatedOperationDataDefinition = optionalOperationDataDefinition.get();
343         updatedOperationDataDefinition.setUniqueId(UUID.randomUUID().toString());
344         updatedOperationDataDefinition.getImplementation()
345             .setArtifactName(generateArtifactName(updatedOperationDataDefinition.getImplementation().getArtifactName()));
346
347         List<ComponentInstanceInterface> componentInstanceInterfaceList = componentInstancesInterfaceMap.get(componentInstanceId);
348         componentInstanceInterfaceList = CollectionUtils.isEmpty(componentInstanceInterfaceList) ? new ArrayList<>() : componentInstanceInterfaceList;
349         Optional<ComponentInstanceInterface> componentInstanceInterface =
350             componentInstanceInterfaceList.stream().filter(instInterface -> instInterface.getInterfaceId().equals(interfaceKey)).findFirst();
351
352         if (componentInstanceInterface.isEmpty()) {
353             componentInstanceInterfaceList.add(new ComponentInstanceInterface(interfaceKey, interfaceDefinition));
354             componentInstanceOptional.get().addInterface(interfaceKey, interfaceDefinition);
355         } else {
356             componentInstanceInterface.get().getOperations().put(updatedOperationDataDefinition.getName(), updatedOperationDataDefinition);
357         }
358
359         boolean wasLocked = false;
360         try {
361             if (shouldLock) {
362                 lockComponent(componentId, component, UPDATE_INTERFACE_OPERATION_ON_COMPONENT_INSTANCE);
363                 wasLocked = true;
364             }
365             StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceInterfaces(component, componentInstanceId);
366             if (status != StorageOperationStatus.OK) {
367                 janusGraphDao.rollback();
368                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
369                 LOGGER.error(EXCEPTION_OCCURRED_WHEN_UPDATING_COMPONENT_INSTANCE_INTERFACES, responseFormat);
370                 errorWrapper.setInnerElement(responseFormat);
371                 return Optional.empty();
372             }
373             janusGraphDao.commit();
374         } catch (final Exception e) {
375             janusGraphDao.rollback();
376             LOGGER.error("Exception occurred when updating Interface Operation on Component Instance: {}", e.getMessage(), e);
377             responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
378             errorWrapper.setInnerElement(responseFormat);
379             throw new BusinessLogicException(responseFormat);
380         } finally {
381             if (wasLocked) {
382                 unlockComponent(component.getUniqueId(), componentTypeEnum);
383             }
384         }
385         return componentInstanceOptional;
386     }
387
388     public Optional<Component> createInterfaceOperationInResource(final String componentId, final InterfaceDefinition interfaceDefinition,
389                                                                   final ComponentTypeEnum componentTypeEnum,
390                                                                   final Wrapper<ResponseFormat> errorWrapper, final boolean shouldLock)
391         throws BusinessLogicException {
392         final Component component = getComponent(componentId);
393         ResponseFormat responseFormat;
394         final String componentInterfaceUpdatedKey = interfaceDefinition.getType();
395
396         Map<String, InterfaceDefinition> componentInterfaceMap = component.getInterfaces();
397         if (MapUtils.isEmpty(componentInterfaceMap)) {
398             componentInterfaceMap = new HashMap<>();
399             component.setInterfaces(componentInterfaceMap);
400         }
401
402         interfaceDefinition.setUniqueId(componentInterfaceUpdatedKey);
403         interfaceDefinition.setToscaResourceName(componentInterfaceUpdatedKey);
404         interfaceDefinition.setUserCreated(true);
405
406         final Optional<OperationDataDefinition> optionalOperationDataDefinition = interfaceDefinition.getOperations().values().stream().findFirst();
407         if (optionalOperationDataDefinition.isEmpty()) {
408             responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND);
409             LOGGER.debug("Failed to found interface operation on component instance with id {}, error: {}", componentId, responseFormat);
410             errorWrapper.setInnerElement(responseFormat);
411             return Optional.empty();
412         }
413
414         final OperationDataDefinition updatedOperationDataDefinition = optionalOperationDataDefinition.get();
415         updatedOperationDataDefinition.setUniqueId(UUID.randomUUID().toString());
416         updatedOperationDataDefinition.getImplementation()
417             .setArtifactName(generateArtifactName(updatedOperationDataDefinition.getImplementation().getArtifactName()));
418
419         final InterfaceDefinition interfaceDefinitionFound = componentInterfaceMap.get(componentInterfaceUpdatedKey);
420         if (interfaceDefinitionFound != null) {
421             final Map<String, OperationDataDefinition> operationsFromComponent = interfaceDefinitionFound.getOperations();
422             final String updatedOperationDataDefinitionName = updatedOperationDataDefinition.getName();
423             final boolean find = operationsFromComponent.containsKey(updatedOperationDataDefinitionName);
424             if (find) {
425                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NAME_ALREADY_IN_USE,
426                     updatedOperationDataDefinitionName);
427                 LOGGER.error("Operation '{}' for Interface '{}' already exist, error: '{}'", updatedOperationDataDefinitionName,
428                     componentInterfaceUpdatedKey, responseFormat);
429                 errorWrapper.setInnerElement(responseFormat);
430                 return Optional.empty();
431             } else {
432                 operationsFromComponent.put(updatedOperationDataDefinitionName, updatedOperationDataDefinition);
433                 interfaceDefinition.setOperations(operationsFromComponent);
434             }
435         }
436
437         componentInterfaceMap.put(componentInterfaceUpdatedKey, interfaceDefinition);
438
439         boolean wasLocked = false;
440         try {
441             if (shouldLock) {
442                 lockComponent(componentId, component, UPDATE_INTERFACE_OPERATION_ON_COMPONENT_INSTANCE);
443                 wasLocked = true;
444             }
445             final Either<InterfaceDefinition, StorageOperationStatus> operationStatusEither =
446                 toscaOperationFacade.addInterfaceToComponent(componentInterfaceUpdatedKey, interfaceDefinition, component);
447             if (operationStatusEither.isRight()) {
448                 janusGraphDao.rollback();
449                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
450                 LOGGER.error(EXCEPTION_OCCURRED_WHEN_UPDATING_COMPONENT_INSTANCE_INTERFACES, responseFormat);
451                 errorWrapper.setInnerElement(responseFormat);
452                 return Optional.empty();
453             }
454             janusGraphDao.commit();
455         } catch (final Exception e) {
456             janusGraphDao.rollback();
457             LOGGER.error("Exception occurred when updating Interface Operation on Component Instance: ", e);
458             responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
459             errorWrapper.setInnerElement(responseFormat);
460             throw new BusinessLogicException(responseFormat);
461         } finally {
462             if (wasLocked) {
463                 unlockComponent(component.getUniqueId(), componentTypeEnum);
464             }
465         }
466         return Optional.of(component);
467     }
468
469     private String generateArtifactName(final String name) {
470         if (OperationArtifactUtil.artifactNameIsALiteralValue(name)) {
471             return name;
472         } else {
473             return QUOTE + name + QUOTE;
474         }
475     }
476
477     public User validateUser(final String userId) {
478         final User user = userValidations.validateUserExists(userId);
479         userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
480         return user;
481     }
482
483     private void unlockComponent(final String componentUniqueId, final ComponentTypeEnum componentType) {
484         graphLockOperation.unlockComponent(componentUniqueId, componentType.getNodeType());
485     }
486
487     private void updateOperationDefinitionImplementation(final OperationDataDefinition updatedOperationDataDefinition) {
488         final ArtifactDataDefinition artifactInfo = new ArtifactDataDefinition(updatedOperationDataDefinition.getImplementation());
489         artifactInfo.setArtifactName(String.format("'%s'", updatedOperationDataDefinition.getImplementation().getArtifactName()));
490         updatedOperationDataDefinition.setImplementation(artifactInfo);
491     }
492
493     private List<PropertyDefinition> convertOperationInputsToPropertyDefinitions(final OperationDataDefinition operationDataDefinition) {
494         List<PropertyDefinition> propertyDefinitions = new ArrayList<>();
495         ListDataDefinition<OperationInputDefinition> inputsDefinitionListData = operationDataDefinition.getInputs();
496         if (null != inputsDefinitionListData && !inputsDefinitionListData.isEmpty()) {
497             List<OperationInputDefinition> inputDefinitionList =
498                 inputsDefinitionListData.getListToscaDataDefinition();
499             for (OperationInputDefinition operationInputDefinition : inputDefinitionList) {
500                 PropertyDefinition propertyDefinition = new PropertyDefinition();
501                 propertyDefinition.setValue(operationInputDefinition.getValue());
502                 propertyDefinition.setUniqueId(operationInputDefinition.getUniqueId());
503                 propertyDefinition.setType(operationInputDefinition.getType());
504                 propertyDefinition.setName(operationInputDefinition.getName());
505                 propertyDefinition.setDefaultValue(operationInputDefinition.getDefaultValue());
506                 propertyDefinition.setInputPath(operationInputDefinition.getInputPath());
507                 propertyDefinitions.add(propertyDefinition);
508             }
509         }
510         return propertyDefinitions;
511     }
512
513     private List<PropertyDefinition> convertOperationArtifactPropsToPropertyDefinitions(final OperationDataDefinition operationDataDefinition,
514                                                                                         final String model) {
515         List<PropertyDefinition> artifactPropertiesToValidateCollection = new ArrayList<>();
516         final ArtifactDataDefinition artifactDataDefinition = operationDataDefinition.getImplementation();
517         if (null != artifactDataDefinition) {
518             final String artifactType = artifactDataDefinition.getArtifactType();
519             final String uniqueId = UniqueIdBuilder.buildArtifactTypeUid(model, artifactType);
520             ArtifactTypeDefinition retrievedArtifact = artifactTypeBusinessLogic.getArtifactTypeByUid(uniqueId);
521             if (retrievedArtifact != null) {
522                 List<PropertyDataDefinition> artifactPropertiesList = artifactDataDefinition.getProperties();
523                 if (null != artifactPropertiesList && !artifactPropertiesList.isEmpty()) {
524                     for (PropertyDataDefinition propertyDataDefinition : artifactPropertiesList) {
525                         PropertyDefinition propertyDefinition = new PropertyDefinition();
526                         propertyDefinition.setConstraints(deserializePropertyConstraints(propertyDataDefinition.getPropertyConstraints()));
527                         propertyDefinition.setValue(propertyDataDefinition.getValue());
528                         propertyDefinition.setType(propertyDataDefinition.getType());
529                         propertyDefinition.setName(propertyDataDefinition.getName());
530                         propertyDefinition.setDefaultValue(propertyDataDefinition.getDefaultValue());
531                         propertyDefinition.setInputPath(propertyDataDefinition.getInputPath());
532                         artifactPropertiesToValidateCollection.add(propertyDefinition);
533                     }
534                 }
535             }
536         }
537         return artifactPropertiesToValidateCollection;
538     }
539
540     private List<PropertyConstraint> deserializePropertyConstraints(List<String> constraints) {
541         if (CollectionUtils.isNotEmpty(constraints)) {
542             Type constraintType = new TypeToken<PropertyConstraint>() {
543             }.getType();
544             Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyOperation.PropertyConstraintDeserialiser()).create();
545             return constraints.stream().map(c -> (PropertyConstraint) gson.fromJson(c, constraintType)).collect(
546                 Collectors.toList());
547         }
548         return null;
549     }
550 }