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