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