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