8ee186486273dcad504a479043a1f586a4b03abb
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / BaseBusinessLogic.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. 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  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.be.components.impl;
22
23 import com.google.gson.JsonElement;
24 import fj.data.Either;
25 import org.apache.commons.lang3.tuple.ImmutablePair;
26 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
27 import org.openecomp.sdc.be.components.validation.UserValidations;
28 import org.openecomp.sdc.be.config.BeEcompErrorManager;
29 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
30 import org.openecomp.sdc.be.dao.api.ActionStatus;
31 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
32 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
33 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
34 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
35 import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
36 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
37 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
38 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
39 import org.openecomp.sdc.be.impl.ComponentsUtils;
40 import org.openecomp.sdc.be.model.*;
41 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
42 import org.openecomp.sdc.be.model.jsontitan.operations.ArtifactsOperations;
43 import org.openecomp.sdc.be.model.jsontitan.operations.InterfaceOperation;
44 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
45 import org.openecomp.sdc.be.model.operations.StorageException;
46 import org.openecomp.sdc.be.model.operations.api.*;
47 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
48 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
49 import org.openecomp.sdc.be.model.operations.impl.PolicyTypeOperation;
50 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
51 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
52 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
53 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
54 import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter;
55 import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
56 import org.openecomp.sdc.be.user.IUserBusinessLogic;
57 import org.openecomp.sdc.be.user.Role;
58 import org.openecomp.sdc.be.user.UserBusinessLogic;
59 import org.openecomp.sdc.common.datastructure.Wrapper;
60 import org.openecomp.sdc.common.log.wrappers.Logger;
61 import org.openecomp.sdc.exception.ResponseFormat;
62 import org.springframework.beans.factory.annotation.Autowired;
63
64 import java.util.Arrays;
65 import java.util.List;
66 import java.util.Map;
67 import java.util.function.Function;
68
69 public abstract class BaseBusinessLogic {
70
71     private static final String FAILED_TO_LOCK_COMPONENT_ERROR = "Failed to lock component {} error - {}";
72
73         private static final Logger log = Logger.getLogger(BaseBusinessLogic.class.getName());
74
75     private static final String EMPTY_VALUE = null;
76     private static final String SCHEMA_DOESN_T_EXISTS_FOR_PROPERTY_OF_TYPE = "Schema doesn't exists for property of type {}";
77     private static final String PROPERTY_IN_SCHEMA_DEFINITION_INSIDE_PROPERTY_OF_TYPE_DOESN_T_EXIST = "Property in Schema Definition inside property of type {} doesn't exist";
78     private static final String ADD_PROPERTY_VALUE = "Add property value";
79     @Autowired
80     protected ComponentsUtils componentsUtils;
81
82     @Autowired
83     protected IUserBusinessLogic userAdmin;
84
85     @Autowired
86     protected IGraphLockOperation graphLockOperation;
87
88     @Autowired
89     protected TitanDao titanDao;
90
91     @Autowired
92     protected TitanGenericDao titanGenericDao;
93
94     @Autowired
95     protected IElementOperation elementDao;
96
97     @Autowired
98     protected IGroupOperation groupOperation;
99
100     @Autowired
101     IGroupInstanceOperation groupInstanceOperation;
102
103     @Autowired
104     protected IGroupTypeOperation groupTypeOperation;
105
106     @Autowired
107     protected GroupBusinessLogic groupBusinessLogic;
108
109     @Autowired
110     PolicyTypeOperation policyTypeOperation;
111
112     @javax.annotation.Resource
113     protected ArtifactsOperations artifactToscaOperation;
114
115     @Autowired
116     protected PropertyOperation propertyOperation;
117
118     @Autowired
119     protected ApplicationDataTypeCache applicationDataTypeCache;
120
121     @Autowired
122     protected ToscaOperationFacade toscaOperationFacade;
123
124     @Autowired
125     protected ApplicationDataTypeCache dataTypeCache;
126
127     @Autowired
128     protected InterfaceOperation interfaceOperation;
129
130     @Autowired
131     protected InterfaceLifecycleOperation interfaceLifecycleTypeOperation;
132
133     @javax.annotation.Resource
134     private UserValidations userValidations;
135
136     DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
137
138
139     public void setUserAdmin(UserBusinessLogic userAdmin) {
140         this.userAdmin = userAdmin;
141     }
142
143     public void setUserValidations(UserValidations userValidations) {
144         this.userValidations = userValidations;
145     }
146
147     public void setComponentsUtils(ComponentsUtils componentsUtils) {
148         this.componentsUtils = componentsUtils;
149     }
150
151     public void setGraphLockOperation(IGraphLockOperation graphLockOperation) {
152         this.graphLockOperation = graphLockOperation;
153     }
154
155     public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
156         this.toscaOperationFacade = toscaOperationFacade;
157     }
158
159     public void setDataTypeCache(ApplicationDataTypeCache dataTypeCache) {
160         this.dataTypeCache = dataTypeCache;
161     }
162
163     public void setPropertyOperation(PropertyOperation propertyOperation) {
164         this.propertyOperation = propertyOperation;
165     }
166
167     User validateUserNotEmpty(User user, String ecompErrorContext) {
168         return userValidations.validateUserNotEmpty(user, ecompErrorContext);
169     }
170
171     protected User validateUserExists(User user, String ecompErrorContext, boolean inTransaction) {
172         return userValidations.validateUserExists(user.getUserId(), ecompErrorContext, inTransaction);
173     }
174
175     void validateUserExist(String userId, String ecompErrorContext) {
176         userValidations.validateUserExist(userId, ecompErrorContext);
177     }
178
179     Either<User, ActionStatus> validateUserExistsActionStatus(String userId, String ecompErrorContext) {
180         return userValidations.validateUserExistsActionStatus(userId, ecompErrorContext);
181     }
182
183     public User validateUserExists(String userId, String ecompErrorContext, boolean inTransaction) {
184         return userValidations.validateUserExists(userId, ecompErrorContext, inTransaction);
185     }
186
187     protected void validateUserRole(User user, List<Role> roles) {
188         userValidations.validateUserRole(user, roles);
189     }
190
191     protected Either<Boolean, ResponseFormat> lockComponent(Component component, String ecompErrorContext) {
192         return lockComponent(component.getUniqueId(), component, ecompErrorContext);
193     }
194
195     protected Either<Component, ResponseFormat> lockComponent(Component component, boolean shoulLock, String ecompErrorContext) {
196         return shoulLock ? lockComponent(component.getUniqueId(), component, ecompErrorContext)
197                 .either(l -> Either.left(component), Either::right) : Either.left(component);
198     }
199
200     protected Either<Boolean, ResponseFormat> lockComponent(String componentId, Component component, String ecompErrorContext) {
201         return lockElement( componentId,  component,  ecompErrorContext)
202                 .right()
203                 .map(r -> logAndConvertError(r, component.getUniqueId(), component.getName()) );
204     }
205
206     protected void lockComponent(String componentId, Component component, boolean needLock, String ecompErrorContext) {
207         if (needLock){
208             lockElement( componentId,  component,  ecompErrorContext)
209                    .left()
210                    .on(r -> logAndThrowException(r, component.getUniqueId(), component.getName()) );
211         }
212     }
213
214     private Boolean logAndThrowException(ActionStatus status, String componentId, String name){
215         log.debug(FAILED_TO_LOCK_COMPONENT_ERROR, componentId, status);
216         throw new ComponentException(status, name);
217     }
218
219     private ResponseFormat logAndConvertError(ActionStatus status, String componentId, String name){
220         ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, name);
221         log.debug(FAILED_TO_LOCK_COMPONENT_ERROR, componentId, status);
222         return responseFormat;
223     }
224
225     private Either<Boolean, ActionStatus> lockElement(String componentId, Component component, String ecompErrorContext) {
226         ComponentTypeEnum componentType = component.getComponentType();
227         NodeTypeEnum nodeType = componentType.getNodeType();
228         StorageOperationStatus lockResourceStatus = graphLockOperation.lockComponent(componentId, nodeType);
229
230         if (lockResourceStatus.equals(StorageOperationStatus.OK)) {
231             return Either.left(true);
232         } else {
233             BeEcompErrorManager.getInstance().logBeFailedLockObjectError(ecompErrorContext, nodeType.getName(), componentId);
234             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(lockResourceStatus, componentType);
235             return Either.right(actionStatus);
236         }
237     }
238
239     protected void unlockComponent(Either<?, ?> either, Component component, boolean inTransaction) {
240         ComponentTypeEnum componentType = component.getComponentType();
241         NodeTypeEnum nodeType = componentType.getNodeType();
242         if (!inTransaction) {
243             if (either == null || either.isRight()) {
244                 titanDao.rollback();
245             } else {
246                 titanDao.commit();
247             }
248         }
249         // unlock resource
250         graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
251     }
252
253     protected void unlockComponent(Either<?, ?> either, Component component) {
254         unlockComponent(either, component, false);
255     }
256     void unlockComponentById(Either<?, ?> either, String componentId) {
257         Either<Component, StorageOperationStatus> component = toscaOperationFacade.getToscaElement(componentId);
258         if(component.isLeft()) {
259             unlockComponent(either, component.left().value(), false);
260         }
261     }
262
263     <T> Either<Boolean, ResponseFormat> validateJsonBody(T bodyObject, Class<T> clazz) {
264         if (bodyObject == null) {
265             log.debug("Invalid JSON received for object of type {}", clazz.getSimpleName());
266             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
267         } else {
268             return Either.left(true);
269         }
270     }
271
272     Either<ComponentTypeEnum, ResponseFormat> validateComponentType(String componentType) {
273         ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
274         if (componentTypeEnum == null) {
275             log.debug("Invalid component type {}", componentType);
276             return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, componentType));
277         } else {
278             return Either.left(componentTypeEnum);
279         }
280     }
281
282     protected Either<Component, ResponseFormat> validateComponentExists(String componentId, ComponentTypeEnum componentType, ComponentParametersView filter) {
283         return toscaOperationFacade.getToscaElement(componentId, filter == null ? new ComponentParametersView() : filter)
284                 .right()
285                 .map(err -> handleGetComponentError(componentId, componentType, err))
286                 .left()
287                 .bind(cmpt -> validateComponentType(cmpt, componentType));
288     }
289
290     private Either<Component, ResponseFormat> validateComponentType(Component cmpt, ComponentTypeEnum componentType) {
291         if (componentType != cmpt.getComponentType()) {
292             log.debug("component {} is not of requested type {}", cmpt.getUniqueId(), componentType);
293             ActionStatus cmptNotFoundError = componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, componentType);
294             return Either.right(componentsUtils.getResponseFormat(cmptNotFoundError));
295         }
296         return Either.left(cmpt);
297     }
298
299     <T extends PropertyDataDefinition> Either<String, ResponseFormat> updateInputPropertyObjectValue(T property) {
300         Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypesEither = dataTypeCache.getAll();
301         if (allDataTypesEither.isRight()) {
302             TitanOperationStatus status = allDataTypesEither.right().value();
303             BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR);
304             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(status))));
305         }
306         Map<String, DataTypeDefinition> allDataTypes = allDataTypesEither.left().value();
307         String propertyType = property.getType();
308         String innerType = getInnerType(property);
309         // Specific Update Logic
310         Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, property.getValue(), true, innerType, allDataTypes);
311         String newValue = property.getValue();
312         if (isValid.isRight()) {
313             Boolean res = isValid.right().value();
314             if (Boolean.FALSE.equals(res)) {
315                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT))));
316             }
317         } else {
318             Object object = isValid.left().value();
319             if (object != null) {
320                 newValue = object.toString();
321             }
322         }
323         return Either.left(newValue);
324     }
325
326     private <T extends PropertyDataDefinition> String getInnerType(T property){
327         ToscaPropertyType type = ToscaPropertyType.isValidType(property.getType());
328         log.debug("#getInnerType - The type of the property {} is {}", property.getUniqueId(), property.getType());
329         String innerType = null;
330         if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
331             if (property.getSchema() == null) {
332                 log.debug(SCHEMA_DOESN_T_EXISTS_FOR_PROPERTY_OF_TYPE, type);
333                 throw new ComponentException(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE));
334             }
335             PropertyDataDefinition innerProperty = property.getSchema().getProperty();
336             if (innerProperty == null) {
337                 log.debug(PROPERTY_IN_SCHEMA_DEFINITION_INSIDE_PROPERTY_OF_TYPE_DOESN_T_EXIST, type);
338                 throw new ComponentException(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE));
339             }
340             innerType = innerProperty.getType();
341         }
342         return innerType;
343     }
344
345     public Either<Boolean, ResponseFormat> validateCanWorkOnComponent(Component component, String userId) {
346         Either<Boolean, ResponseFormat> canWork = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
347         if (component.getLifecycleState() != LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) {
348             log.debug("Component {} is not checked-out", component.getName());
349             return canWork;
350         }
351
352         // verify userId is not null
353         if (userId == null) {
354             log.debug("Current user userId is null");
355             return canWork;
356         }
357
358         // verify component last update user is the current user
359         String lastUpdaterUserId = component.getLastUpdaterUserId();
360         if (!userId.equals(lastUpdaterUserId)) {
361             log.debug("Current user is not last updater, last updater userId: {}, current user userId: {}", lastUpdaterUserId, userId);
362             return canWork;
363         }
364
365         // verify resource is not deleted
366         if (Boolean.TRUE.equals(component.getIsDeleted())) {
367             log.debug("Component {} is marked as deleted", component.getUniqueId());
368             return canWork;
369         }
370
371         return Either.left(true);
372     }
373
374     ComponentTypeEnum getComponentTypeByParentComponentType(ComponentTypeEnum parentComponentType) {
375         switch (parentComponentType) {
376             case SERVICE:
377                 return ComponentTypeEnum.RESOURCE;
378             case RESOURCE:
379                 return ComponentTypeEnum.RESOURCE;
380             case PRODUCT:
381                 return ComponentTypeEnum.SERVICE;
382             default:
383                 break;
384         }
385         return null;
386     }
387
388     // For UT
389     public void setTitanGenericDao(TitanDao titanDao) {
390         this.titanDao = titanDao;
391     }
392
393     protected Either<Map<String, DataTypeDefinition>, ResponseFormat> getAllDataTypes(ApplicationDataTypeCache applicationDataTypeCache) {
394         Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = applicationDataTypeCache.getAll();
395         if (allDataTypes.isRight()) {
396             TitanOperationStatus operationStatus = allDataTypes.right().value();
397             if (operationStatus == TitanOperationStatus.NOT_FOUND) {
398                 BeEcompErrorManager.getInstance().logInternalDataError("FetchDataTypes", "Data types are not loaded", ErrorSeverity.ERROR);
399                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.DATA_TYPE_CANNOT_BE_EMPTY));
400             } else {
401                 BeEcompErrorManager.getInstance().logInternalFlowError("FetchDataTypes", "Failed to fetch data types", ErrorSeverity.ERROR);
402                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
403             }
404         }
405         return Either.left(allDataTypes.left().value());
406     }
407
408     Either<Boolean, ResponseFormat> validatePropertyDefaultValue(IComplexDefaultValue property, Map<String, DataTypeDefinition> dataTypes) {
409         String type;
410         String innerType = null;
411         if (!propertyOperation.isPropertyTypeValid(property)) {
412             log.info("Invalid type for property {} type {}", property.getName(), property.getType());
413             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_TYPE, property.getType(), property.getName());
414             return Either.right(responseFormat);
415         }
416         type = property.getType();
417         if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
418             ImmutablePair<String, Boolean> propertyInnerTypeValid = propertyOperation.isPropertyInnerTypeValid(property, dataTypes);
419             innerType = propertyInnerTypeValid.getLeft();
420             if (!propertyInnerTypeValid.getRight()) {
421                 log.info("Invalid inner type for property {} type {}", property.getName(), property.getType());
422                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE, innerType, property.getName());
423                 return Either.right(responseFormat);
424             }
425         }
426         if (!propertyOperation.isPropertyDefaultValueValid(property, dataTypes)) {
427             log.info("Invalid default value for property {} type {}", property.getName(), property.getType());
428             ResponseFormat responseFormat;
429             if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
430                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE, property.getName(), type, innerType, property.getDefaultValue());
431             } else {
432                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEFAULT_VALUE, property.getName(), type, property.getDefaultValue());
433             }
434             return Either.right(responseFormat);
435
436         }
437         return Either.left(true);
438     }
439
440
441     void handleDefaultValue(IComplexDefaultValue newAttributeDef, Map<String, DataTypeDefinition> dataTypes) {
442         // convert property
443         ToscaPropertyType type = ToscaPropertyType.isValidType(newAttributeDef.getType());
444         PropertyValueConverter converter = type.getConverter();
445         // get inner type
446         String innerType = null;
447
448         SchemaDefinition schema = newAttributeDef.getSchema();
449         if (schema != null) {
450             PropertyDataDefinition prop = schema.getProperty();
451             if (schema.getProperty() != null) {
452                 innerType = prop.getType();
453             }
454         }
455         String convertedValue;
456         if (newAttributeDef.getDefaultValue() != null) {
457             convertedValue = converter.convert(newAttributeDef.getDefaultValue(), innerType, dataTypes);
458             newAttributeDef.setDefaultValue(convertedValue);
459         }
460     }
461
462     void validateComponentTypeEnum(ComponentTypeEnum componentTypeEnum, String errorContext, Wrapper<ResponseFormat> errorWrapper) {
463         if (componentTypeEnum == null) {
464             BeEcompErrorManager.getInstance().logInvalidInputError(errorContext, "invalid component type", ErrorSeverity.INFO);
465             errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
466         }
467
468     }
469
470     protected void validateCanWorkOnComponent(String componentId, ComponentTypeEnum componentTypeEnum, String userId, Wrapper<ResponseFormat> errorWrapper) {
471         if (!ComponentValidationUtils.canWorkOnComponent(componentId, toscaOperationFacade, userId)) {
472             log.info("Restricted operation for user {} on {} {}", userId, componentTypeEnum.getValue(), componentId);
473             errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
474         }
475
476     }
477
478     void validateComponentLock(String componentId, ComponentTypeEnum componentTypeEnum, Wrapper<ResponseFormat> errorWrapper) {
479         StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType());
480         if (lockStatus != StorageOperationStatus.OK) {
481             log.debug("Failed to lock {} {}", componentTypeEnum.getValue(), componentId);
482             errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
483         }
484
485     }
486
487     protected ToscaPropertyType getType(String propertyType) {
488         return ToscaPropertyType.isValidType(propertyType);
489     }
490
491     void commitOrRollback(Either<?, ResponseFormat> result) {
492         if (result == null || result.isRight()) {
493             log.warn("operation failed. do rollback");
494             titanDao.rollback();
495         } else {
496             log.debug("operation success. do commit");
497             titanDao.commit();
498         }
499     }
500
501     protected Either<Boolean, ResponseFormat> lockComponentByName(String name, Component component, String ecompErrorContext) {
502         ComponentTypeEnum componentType = component.getComponentType();
503         NodeTypeEnum nodeType = componentType.getNodeType();
504         StorageOperationStatus lockResourceStatus = graphLockOperation.lockComponentByName(name, nodeType);
505
506         if (lockResourceStatus.equals(StorageOperationStatus.OK)) {
507             return Either.left(true);
508         } else {
509             BeEcompErrorManager.getInstance().logBeFailedLockObjectError(ecompErrorContext, nodeType.getName(), name);
510             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(lockResourceStatus, componentType);
511             ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, component.getName());
512             log.debug(FAILED_TO_LOCK_COMPONENT_ERROR, name, actionStatus);
513             return Either.right(responseFormat);
514         }
515     }
516
517     protected Either<Component, ResponseFormat> validateComponentExistsByFilter(String componentId, ComponentTypeEnum componentType, ComponentParametersView componentParametersView) {
518         return toscaOperationFacade.getToscaElement(componentId, componentParametersView)
519                 .right()
520                 .map(err -> handleGetComponentError(componentId, componentType, err));
521
522     }
523
524     private ResponseFormat handleGetComponentError(String componentId, ComponentTypeEnum componentType, StorageOperationStatus getComponentError) {
525         ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentError, componentType);
526         ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, componentId);
527         log.debug("error fetching component with id {}. error status: {}", componentId, getComponentError);
528         return responseFormat;
529     }
530
531     @SafeVarargs
532     static <T extends Enum<T>> boolean enumHasValueFilter(String name, Function<String, T> enumGetter, T... enumValues) {
533         T enumFound = enumGetter.apply(name);
534         return Arrays.asList(enumValues).contains(enumFound);
535     }
536
537     String validatePropValueBeforeCreate(IPropertyInputCommon property, String value, boolean isValidate, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
538         String propertyType = property.getType();
539         String updatedInnerType = updateInnerType(property, innerType);
540         Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value, isValidate, updatedInnerType, allDataTypes);
541         String newValue = value;
542         if (isValid.isRight()) {
543             Boolean res = isValid.right().value();
544             if (Boolean.FALSE.equals(res)) {
545                 throw new StorageException(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
546             }
547         } else {
548             Object object = isValid.left().value();
549             if (object != null) {
550                 newValue = object.toString();
551             }
552         }
553         ImmutablePair<String, Boolean> pair = validateAndUpdateRules(propertyType, property.getRules(), updatedInnerType, allDataTypes, isValidate);
554         log.trace("After validateAndUpdateRules. pair = {}", pair);
555         if (Boolean.FALSE.equals(pair.getRight())) {
556             BeEcompErrorManager.getInstance().logBeInvalidValueError(ADD_PROPERTY_VALUE, pair.getLeft(), property.getName(), propertyType);
557             throw new StorageException(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
558         }
559         return newValue;
560     }
561
562     private String updateInnerType(IPropertyInputCommon property, String innerType) {
563         ToscaPropertyType type = ToscaPropertyType.isValidType(property.getType());
564         if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
565             SchemaDefinition def = property.getSchema();
566             if (def == null) {
567                 log.debug(SCHEMA_DOESN_T_EXISTS_FOR_PROPERTY_OF_TYPE, type);
568                 failOnIllegalArgument();
569             }
570             PropertyDataDefinition propDef = def.getProperty();
571             if (propDef == null) {
572                 log.debug(PROPERTY_IN_SCHEMA_DEFINITION_INSIDE_PROPERTY_OF_TYPE_DOESN_T_EXIST, type);
573                 failOnIllegalArgument();
574             }
575             return propDef.getType();
576         }
577         return innerType;
578     }
579
580     private void failOnIllegalArgument() {
581         throw new ComponentException(
582                 componentsUtils.convertFromStorageResponse(
583                         DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT)));
584     }
585
586     public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, boolean isValidate, String innerType, Map<String, DataTypeDefinition> dataTypes) {
587         log.trace("Going to validate property value and its type. type = {}, value = {}", propertyType, value);
588         ToscaPropertyType type = getType(propertyType);
589
590         if (isValidate) {
591
592             if (type == null) {
593                 DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
594                 ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, dataTypes);
595                 if (Boolean.FALSE.equals(validateResult.right)) {
596                     log.debug("The value {} of property from type {} is invalid", value, propertyType);
597                     return Either.right(false);
598                 }
599                 JsonElement jsonElement = validateResult.left;
600                 String valueFromJsonElement = getValueFromJsonElement(jsonElement);
601                 return Either.left(valueFromJsonElement);
602             }
603             log.trace("before validating property type {}", propertyType);
604             boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
605             if (!isValidProperty) {
606                 log.debug("The value {} of property from type {} is invalid", value, type);
607                 return Either.right(false);
608             }
609         }
610         Object convertedValue = value;
611         if (!isEmptyValue(value) && isValidate) {
612             PropertyValueConverter converter = type.getConverter();
613             convertedValue = converter.convert(value, innerType, dataTypes);
614         }
615         return Either.left(convertedValue);
616     }
617
618     private ImmutablePair<String, Boolean> validateAndUpdateRules(String propertyType, List<PropertyRule> rules, String innerType, Map<String, DataTypeDefinition> dataTypes, boolean isValidate) {
619
620         if (rules == null || rules.isEmpty()) {
621             return ImmutablePair.of(null, true);
622         }
623
624         for (PropertyRule rule : rules) {
625             String value = rule.getValue();
626             Either<Object, Boolean> updateResult = validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, dataTypes);
627             if (updateResult.isRight()) {
628                 Boolean status = updateResult.right().value();
629                 if (Boolean.FALSE.equals(status)) {
630                     return ImmutablePair.of(value, status);
631                 }
632             } else {
633                 String newValue = null;
634                 Object object = updateResult.left().value();
635                 if (object != null) {
636                     newValue = object.toString();
637                 }
638                 rule.setValue(newValue);
639             }
640         }
641
642         return ImmutablePair.of(null, true);
643     }
644
645     protected boolean isValidValue(ToscaPropertyType type, String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
646         if (isEmptyValue(value)) {
647             return true;
648         }
649
650         PropertyTypeValidator validator = type.getValidator();
651
652         return validator.isValid(value, innerType, dataTypes);
653     }
654
655     public boolean isEmptyValue(String value) {
656         return value == null;
657     }
658
659     protected String getValueFromJsonElement(JsonElement jsonElement) {
660         if (jsonElement == null || jsonElement.isJsonNull()) {
661             return EMPTY_VALUE;
662         }
663         if (jsonElement.toString().isEmpty()) {
664             return "";
665         }
666         return jsonElement.toString();
667     }
668     
669     protected void rollbackWithException(ActionStatus actionStatus, String... params) {
670         titanDao.rollback();
671         throw new ComponentException(actionStatus, params);
672     }
673 }