Catalog alignment
[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  * Modifications copyright (c) 2019 Nokia
20  * ================================================================================
21  */
22
23 package org.openecomp.sdc.be.components.impl;
24
25 import com.google.gson.JsonElement;
26 import fj.data.Either;
27 import org.apache.commons.lang3.ArrayUtils;
28 import org.apache.commons.lang3.StringUtils;
29 import org.apache.commons.lang3.tuple.ImmutablePair;
30 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
31 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
32 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
33 import org.openecomp.sdc.be.components.validation.UserValidations;
34 import org.openecomp.sdc.be.config.BeEcompErrorManager;
35 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
36 import org.openecomp.sdc.be.dao.api.ActionStatus;
37 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao;
38 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
39 import org.openecomp.sdc.be.dao.jsongraph.JanusGraphDao;
40 import org.openecomp.sdc.be.datamodel.utils.ArtifactUtils;
41 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
42 import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
43 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
44 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
45 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
46 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
47 import org.openecomp.sdc.be.impl.ComponentsUtils;
48 import org.openecomp.sdc.be.model.ArtifactDefinition;
49 import org.openecomp.sdc.be.model.Component;
50 import org.openecomp.sdc.be.model.ComponentInstInputsMap;
51 import org.openecomp.sdc.be.model.ComponentInstance;
52 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
53 import org.openecomp.sdc.be.model.ComponentParametersView;
54 import org.openecomp.sdc.be.model.DataTypeDefinition;
55 import org.openecomp.sdc.be.model.IComplexDefaultValue;
56 import org.openecomp.sdc.be.model.IPropertyInputCommon;
57 import org.openecomp.sdc.be.model.LifecycleStateEnum;
58 import org.openecomp.sdc.be.model.PolicyDefinition;
59 import org.openecomp.sdc.be.model.PropertyConstraint;
60 import org.openecomp.sdc.be.model.PropertyDefinition;
61 import org.openecomp.sdc.be.model.User;
62 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
63 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
64 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
65 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
66 import org.openecomp.sdc.be.model.operations.StorageException;
67 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
68 import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
69 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
70 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
71 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
72 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
73 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
74 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
75 import org.openecomp.sdc.be.model.operations.impl.PolicyTypeOperation;
76 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
77 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
78 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
79 import org.openecomp.sdc.be.model.tosca.ToscaType;
80 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
81 import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter;
82 import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
83 import org.openecomp.sdc.be.user.Role;
84 import org.openecomp.sdc.be.user.UserBusinessLogic;
85 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
86 import org.openecomp.sdc.common.datastructure.Wrapper;
87 import org.openecomp.sdc.common.log.wrappers.Logger;
88 import org.openecomp.sdc.exception.ResponseFormat;
89 import org.springframework.beans.factory.annotation.Autowired;
90
91 import java.util.ArrayList;
92 import java.util.Arrays;
93 import java.util.Collections;
94 import java.util.List;
95 import java.util.Map;
96 import java.util.function.Function;
97
98 public abstract class BaseBusinessLogic {
99
100     private static final String FAILED_TO_LOCK_COMPONENT_ERROR = "Failed to lock component {} error - {}";
101
102     private static final Logger log = Logger.getLogger(BaseBusinessLogic.class.getName());
103     private static final String EMPTY_VALUE = null;
104     private static final String SCHEMA_DOESN_T_EXISTS_FOR_PROPERTY_OF_TYPE = "Schema doesn't exists for property of type {}";
105     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";
106     private static final String ADD_PROPERTY_VALUE = "Add property value";
107     private static final String THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID = "The value {} of property from type {} is invalid";
108     protected IGroupTypeOperation groupTypeOperation;
109     protected InterfaceOperation interfaceOperation;
110     protected IElementOperation elementDao;
111     protected ComponentsUtils componentsUtils;
112     protected UserBusinessLogic userAdmin;
113     protected IGraphLockOperation graphLockOperation;
114     protected JanusGraphDao janusGraphDao;
115     protected JanusGraphGenericDao janusGraphGenericDao;
116     protected PropertyOperation propertyOperation;
117     protected ApplicationDataTypeCache applicationDataTypeCache;
118     protected ToscaOperationFacade toscaOperationFacade;
119     protected ApplicationDataTypeCache dataTypeCache;
120     protected IGroupOperation groupOperation;
121     protected IGroupInstanceOperation groupInstanceOperation;
122     protected InterfaceLifecycleOperation interfaceLifecycleTypeOperation;
123     protected PolicyTypeOperation policyTypeOperation;
124     protected  ArtifactsOperations artifactToscaOperation;
125     protected UserValidations userValidations;
126
127     DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
128
129     public BaseBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation,
130         IGroupInstanceOperation groupInstanceOperation, IGroupTypeOperation groupTypeOperation, InterfaceOperation interfaceOperation,
131         InterfaceLifecycleOperation interfaceLifecycleTypeOperation, ArtifactsOperations artifactToscaOperation) {
132         this.elementDao = elementDao;
133         this.groupOperation = groupOperation;
134         this.groupInstanceOperation = groupInstanceOperation;
135         this.groupTypeOperation = groupTypeOperation;
136         this.interfaceOperation = interfaceOperation;
137         this.interfaceLifecycleTypeOperation = interfaceLifecycleTypeOperation;
138         this.artifactToscaOperation = artifactToscaOperation;
139     }
140
141     @Autowired
142     public void setUserAdmin(UserBusinessLogic userAdmin) {
143         this.userAdmin = userAdmin;
144     }
145
146     @Autowired
147     public void setUserValidations(UserValidations userValidations) {
148         this.userValidations = userValidations;
149     }
150
151     @Autowired
152     public void setComponentsUtils(ComponentsUtils componentsUtils) {
153         this.componentsUtils = componentsUtils;
154     }
155
156     @Autowired
157     public void setJanusGraphDao(JanusGraphDao janusGraphDao) {
158         this.janusGraphDao = janusGraphDao;
159     }
160
161     @Autowired
162     public void setApplicationDataTypeCache(ApplicationDataTypeCache applicationDataTypeCache) {
163         this.applicationDataTypeCache = applicationDataTypeCache;
164     }
165
166     @Autowired
167     public void setJanusGraphGenericDao(JanusGraphGenericDao janusGraphGenericDao) {
168         this.janusGraphGenericDao = janusGraphGenericDao;
169     }
170
171     @Autowired
172     public void setGraphLockOperation(IGraphLockOperation graphLockOperation) {
173         this.graphLockOperation = graphLockOperation;
174     }
175
176     @Autowired
177     public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
178         this.toscaOperationFacade = toscaOperationFacade;
179     }
180
181     @Autowired
182     void setPolicyTypeOperation(PolicyTypeOperation policyTypeOperation) {
183         this.policyTypeOperation = policyTypeOperation;
184     }
185
186     @Autowired
187     public void setDataTypeCache(ApplicationDataTypeCache dataTypeCache) {
188         this.dataTypeCache = dataTypeCache;
189     }
190
191     @Autowired
192     public void setPropertyOperation(PropertyOperation propertyOperation) {
193         this.propertyOperation = propertyOperation;
194     }
195
196     User validateUserNotEmpty(User user, String ecompErrorContext) {
197         return userValidations.validateUserNotEmpty(user, ecompErrorContext);
198     }
199
200     protected User validateUserExists(String userId) {
201         return userValidations.validateUserExists(userId);
202     }
203
204     public User validateUserExists(User user) {
205         return userValidations.validateUserExists(user);
206     }
207
208     ActionStatus validateUserExistsActionStatus(String userId) {
209         return userValidations.validateUserExistsActionStatus(userId);
210     }
211
212     protected void validateUserRole(User user, List<Role> roles) {
213         userValidations.validateUserRole(user, roles);
214     }
215
216     protected void lockComponent(Component component, String ecompErrorContext) {
217         lockComponent(component.getUniqueId(), component, ecompErrorContext);
218     }
219
220     protected boolean isVolumeGroup(List<String> artifactsInGroup,List <ArtifactDefinition> deploymentArtifacts) {
221         for (String artifactId : artifactsInGroup) {
222             ArtifactDefinition artifactDef = ArtifactUtils.findArtifactInList(deploymentArtifacts, artifactId);
223             if (artifactDef != null
224                     && artifactDef.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_VOL.getType())) {
225                 return true;
226             }
227         }
228         return false;
229     }
230
231     protected void lockComponent(Component component, boolean shouldLock, String ecompErrorContext) {
232         if(shouldLock){
233             lockComponent(component.getUniqueId(), component, ecompErrorContext);
234         }
235     }
236
237     protected void lockComponent(String componentId, Component component, String ecompErrorContext) {
238         ActionStatus lock = lockElement(componentId, component, ecompErrorContext);
239         if ( lock!= ActionStatus.OK ) {
240             logAndThrowComponentException(lock, component.getUniqueId(), component.getName());
241         }
242     }
243
244     protected void lockComponent(String componentId, Component component, boolean needLock, String ecompErrorContext) {
245         if (needLock) {
246             lockComponent(componentId, component, ecompErrorContext);
247         }
248     }
249
250     private ResponseFormat logAndThrowComponentException(ActionStatus status, String componentId, String name){
251         log.debug(FAILED_TO_LOCK_COMPONENT_ERROR, componentId, status);
252         throw new ByActionStatusComponentException(status, name);
253     }
254
255     private ActionStatus lockElement(String componentId, Component component, String ecompErrorContext) {
256         ComponentTypeEnum componentType = component.getComponentType();
257         NodeTypeEnum nodeType = componentType.getNodeType();
258         StorageOperationStatus lockResourceStatus = graphLockOperation.lockComponent(componentId, nodeType);
259
260         if (lockResourceStatus == StorageOperationStatus.OK) {
261             return ActionStatus.OK;
262         } else {
263             BeEcompErrorManager.getInstance().logBeFailedLockObjectError(ecompErrorContext, nodeType.getName(), componentId);
264             return componentsUtils.convertFromStorageResponse(lockResourceStatus, componentType);
265         }
266     }
267
268     protected void unlockComponent(boolean failed, Component component, boolean inTransaction) {
269         if (component != null) {
270             ComponentTypeEnum componentType = component.getComponentType();
271             NodeTypeEnum nodeType = componentType.getNodeType();
272             if (!inTransaction) {
273                 if (failed) {
274                     janusGraphDao.rollback();
275                 } else {
276                     janusGraphDao.commit();
277                 }
278             }
279             // unlock resource
280             graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
281         }
282         else log.debug("component is NULL");
283     }
284
285     protected void unlockComponent(boolean failed, Component component) {
286         unlockComponent(failed, component, false);
287     }
288     void unlockComponentById(boolean failed, String componentId) {
289         Either<Component, StorageOperationStatus> component = toscaOperationFacade.getToscaElement(componentId);
290         if(component.isLeft()) {
291             unlockComponent(failed, component.left().value(), false);
292         }
293     }
294
295     <T> Boolean validateJsonBody(T bodyObject, Class<T> clazz) {
296         if (bodyObject == null) {
297             log.debug("Invalid JSON received for object of type {}", clazz.getSimpleName());
298             throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
299         } else {
300             return true;
301         }
302     }
303
304
305     ComponentTypeEnum validateComponentType(String componentType) {
306         ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
307         if (componentTypeEnum == null) {
308             log.debug("Invalid component type {}", componentType);
309             throw new ByActionStatusComponentException(ActionStatus.UNSUPPORTED_ERROR, componentType);
310         } else {
311             return componentTypeEnum;
312         }
313     }
314
315     Component validateComponentExists(String componentId, ComponentTypeEnum componentType, ComponentParametersView filter) {
316
317         Either<Component, StorageOperationStatus> toscaElement = toscaOperationFacade.getToscaElement(componentId, filter == null ? new ComponentParametersView() : filter);
318         if(toscaElement.isRight()){
319             handleGetComponentError(componentId, componentType, toscaElement.right().value());
320         }
321         return validateComponentType(toscaElement.left().value(), componentType);
322     }
323
324     private Component validateComponentType(Component cmpt, ComponentTypeEnum componentType) {
325         if (componentType != cmpt.getComponentType()) {
326             log.debug("component {} is not of requested type {}", cmpt.getUniqueId(), componentType);
327             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, componentType));
328         }
329         return cmpt;
330     }
331
332     <T extends PropertyDataDefinition> String updateInputPropertyObjectValue(T property) {
333         Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypesEither = dataTypeCache.getAll();
334         if (allDataTypesEither.isRight()) {
335             JanusGraphOperationStatus status = allDataTypesEither.right().value();
336             BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR);
337             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status)));
338         }
339         Map<String, DataTypeDefinition> allDataTypes = allDataTypesEither.left().value();
340         String propertyType = property.getType();
341         String innerType = getInnerType(property);
342         // Specific Update Logic
343         Either<Object, Boolean> isValid =
344                 propertyOperation.validateAndUpdatePropertyValue(propertyType, (String) property.getValue(), true,
345                         innerType, allDataTypes);
346         String newValue = property.getValue();
347         if (isValid.isRight()) {
348             Boolean res = isValid.right().value();
349             if (Boolean.FALSE.equals(res)) {
350                 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT)));
351             }
352         } else {
353             Object object = isValid.left().value();
354             if (object != null) {
355                 newValue = object.toString();
356             }
357         }
358         return newValue;
359     }
360
361     <T extends PropertyDataDefinition> String getInnerType(T property){
362         ToscaPropertyType type = ToscaPropertyType.isValidType(property.getType());
363         log.debug("#getInnerType - The type of the property {} is {}", property.getUniqueId(), property.getType());
364         String innerType = null;
365         if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
366             if (property.getSchema() == null) {
367                 log.debug(SCHEMA_DOESN_T_EXISTS_FOR_PROPERTY_OF_TYPE, type);
368                 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE));
369             }
370             PropertyDataDefinition innerProperty = property.getSchema().getProperty();
371             if (innerProperty == null) {
372                 log.debug(PROPERTY_IN_SCHEMA_DEFINITION_INSIDE_PROPERTY_OF_TYPE_DOESN_T_EXIST, type);
373                 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE));
374             }
375             innerType = innerProperty.getType();
376         }
377         return innerType;
378     }
379
380     public void validateCanWorkOnComponent(Component component, String userId) {
381         ActionStatus actionStatus = ActionStatus.RESTRICTED_OPERATION;
382         // verify resource is not archived
383         if (component.isArchived() == true){
384             actionStatus = ActionStatus.COMPONENT_IS_ARCHIVED;
385             throw new ByActionStatusComponentException(actionStatus, component.getName());
386         }
387
388         if (component.getLifecycleState() != LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) {
389             log.debug("Component {} is not checked-out", component.getName());
390             throw new ByActionStatusComponentException(actionStatus);
391         }
392
393         // verify userId is not null
394         if (userId == null) {
395             log.debug("Current user userId is null");
396             throw new ByActionStatusComponentException(actionStatus);
397         }
398
399         // verify component last update user is the current user
400         String lastUpdaterUserId = component.getLastUpdaterUserId();
401         if (!userId.equals(lastUpdaterUserId)) {
402             log.debug("Current user is not last updater, last updater userId: {}, current user userId: {}", lastUpdaterUserId, userId);
403             throw new ByActionStatusComponentException(actionStatus);
404         }
405
406         // verify resource is not deleted
407         if (Boolean.TRUE.equals(component.getIsDeleted())) {
408             log.debug("Component {} is marked as deleted", component.getUniqueId());
409             throw new ByActionStatusComponentException(actionStatus);
410         }
411
412     }
413
414
415     ComponentTypeEnum getComponentTypeByParentComponentType(ComponentTypeEnum parentComponentType) {
416         switch (parentComponentType) {
417             case SERVICE:
418             case RESOURCE:
419                 return ComponentTypeEnum.RESOURCE;
420             case PRODUCT:
421                 return ComponentTypeEnum.SERVICE;
422             default:
423                 break;
424         }
425         return null;
426     }
427
428
429
430     protected Map<String, DataTypeDefinition> getAllDataTypes(ApplicationDataTypeCache applicationDataTypeCache) {
431         Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes = applicationDataTypeCache.getAll();
432         if (allDataTypes.isRight()) {
433             JanusGraphOperationStatus operationStatus = allDataTypes.right().value();
434             if (operationStatus == JanusGraphOperationStatus.NOT_FOUND) {
435                 BeEcompErrorManager.getInstance().logInternalDataError("FetchDataTypes", "Data types are not loaded", ErrorSeverity.ERROR);
436                 throw new ByActionStatusComponentException(ActionStatus.DATA_TYPE_CANNOT_BE_EMPTY);
437             } else {
438                 BeEcompErrorManager.getInstance().logInternalFlowError("FetchDataTypes", "Failed to fetch data types", ErrorSeverity.ERROR);
439                 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
440             }
441         }
442         return allDataTypes.left().value();
443     }
444
445     Either<Boolean, ResponseFormat> validatePropertyDefaultValue(IComplexDefaultValue property, Map<String, DataTypeDefinition> dataTypes) {
446         String type;
447         String innerType = null;
448         if (!propertyOperation.isPropertyTypeValid(property)) {
449             log.info("Invalid type for property '{}' type '{}'", property.getName(), property.getType());
450             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_TYPE, property.getType(), property.getName());
451             return Either.right(responseFormat);
452         }
453         type = property.getType();
454         if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
455             ImmutablePair<String, Boolean> propertyInnerTypeValid = propertyOperation.isPropertyInnerTypeValid(property, dataTypes);
456             innerType = propertyInnerTypeValid.getLeft();
457             if (!propertyInnerTypeValid.getRight()) {
458                 log.info("Invalid inner type for property '{}' type '{}', dataTypeCount '{}'", property.getName(), property.getType(), dataTypes.size());
459                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE, innerType, property.getName());
460                 return Either.right(responseFormat);
461             }
462         }
463         if (!propertyOperation.isPropertyDefaultValueValid(property, dataTypes)) {
464             log.info("Invalid default value for property '{}' type '{}'", property.getName(), property.getType());
465             ResponseFormat responseFormat;
466             if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
467                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE, property.getName(), type, innerType,
468                         property.getDefaultValue());
469             } else {
470                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEFAULT_VALUE, property.getName(), type,
471                         property.getDefaultValue());
472             }
473             return Either.right(responseFormat);
474
475         }
476         return Either.left(true);
477     }
478
479
480     void handleDefaultValue(IComplexDefaultValue newAttributeDef, Map<String, DataTypeDefinition> dataTypes) {
481         // convert property
482         ToscaPropertyType type = ToscaPropertyType.isValidType(newAttributeDef.getType());
483         PropertyValueConverter converter = type.getConverter();
484         // get inner type
485         String innerType = null;
486
487         SchemaDefinition schema = newAttributeDef.getSchema();
488         if (schema != null) {
489             PropertyDataDefinition prop = schema.getProperty();
490             if (schema.getProperty() != null) {
491                 innerType = prop.getType();
492             }
493         }
494         String convertedValue;
495         if (newAttributeDef.getDefaultValue() != null) {
496             convertedValue = converter.convert(newAttributeDef.getDefaultValue(), innerType, dataTypes);
497             newAttributeDef.setDefaultValue(convertedValue);
498         }
499     }
500
501     void validateComponentTypeEnum(ComponentTypeEnum componentTypeEnum, String errorContext, Wrapper<ResponseFormat> errorWrapper) {
502         if (componentTypeEnum == null) {
503             BeEcompErrorManager.getInstance().logInvalidInputError(errorContext, "invalid component type", ErrorSeverity.INFO);
504             errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
505         }
506
507     }
508
509     protected void validateCanWorkOnComponent(String componentId, ComponentTypeEnum componentTypeEnum, String userId, Wrapper<ResponseFormat> errorWrapper) {
510         if (!ComponentValidationUtils.canWorkOnComponent(componentId, toscaOperationFacade, userId)) {
511             log.info("Restricted operation for user {} on {} {}", userId, componentTypeEnum.getValue(), componentId);
512             errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
513         }
514
515     }
516
517     void validateComponentLock(String componentId, ComponentTypeEnum componentTypeEnum, Wrapper<ResponseFormat> errorWrapper) {
518         StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType());
519         if (lockStatus != StorageOperationStatus.OK) {
520             log.debug("Failed to lock {} {}", componentTypeEnum.getValue(), componentId);
521             errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
522         }
523
524     }
525
526     protected ToscaPropertyType getType(String propertyType) {
527         return ToscaPropertyType.isValidType(propertyType);
528     }
529
530     void commitOrRollback(Either<?, ResponseFormat> result) {
531         if (result == null || result.isRight()) {
532             log.warn("operation failed. do rollback");
533             janusGraphDao.rollback();
534         } else {
535             log.debug("operation success. do commit");
536             janusGraphDao.commit();
537         }
538     }
539
540     protected Either<Boolean, ResponseFormat> lockComponentByName(String name, Component component, String ecompErrorContext) {
541         ComponentTypeEnum componentType = component.getComponentType();
542         NodeTypeEnum nodeType = componentType.getNodeType();
543         StorageOperationStatus lockResourceStatus = graphLockOperation.lockComponentByName(name, nodeType);
544
545         if (lockResourceStatus == StorageOperationStatus.OK) {
546             return Either.left(true);
547         } else {
548             BeEcompErrorManager.getInstance().logBeFailedLockObjectError(ecompErrorContext, nodeType.getName(), name);
549             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(lockResourceStatus, componentType);
550             ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, component.getName());
551             log.debug(FAILED_TO_LOCK_COMPONENT_ERROR, name, actionStatus);
552             return Either.right(responseFormat);
553         }
554     }
555
556     protected Component validateComponentExistsByFilter(String componentId, ComponentTypeEnum componentType, ComponentParametersView componentParametersView) {
557         return toscaOperationFacade.getToscaElement(componentId, componentParametersView)
558                 .left()
559                 .on(err -> handleGetComponentError(componentId, componentType, err));
560
561     }
562
563     private Component handleGetComponentError(String componentId, ComponentTypeEnum componentType, StorageOperationStatus getComponentError) {
564         ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentError, componentType);
565         log.debug("error fetching component with id {}. error status: {}", componentId, getComponentError);
566         throw new ByActionStatusComponentException(actionStatus, componentId);
567     }
568
569     @SafeVarargs
570     static <T extends Enum<T>> boolean enumHasValueFilter(String name, Function<String, T> enumGetter, T... enumValues) {
571         T enumFound = enumGetter.apply(name);
572         return Arrays.asList(enumValues).contains(enumFound);
573     }
574
575     String validatePropValueBeforeCreate(IPropertyInputCommon property, String value, boolean isValidate,
576         Map<String, DataTypeDefinition> allDataTypes) {
577         String propertyType = property.getType();
578         String updatedInnerType = updateInnerType(property);
579         Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value, isValidate, updatedInnerType, allDataTypes);
580         String newValue = value;
581         if (isValid.isRight()) {
582             Boolean res = isValid.right().value();
583             if (Boolean.FALSE.equals(res)) {
584                 throw new StorageException(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(
585                         JanusGraphOperationStatus.ILLEGAL_ARGUMENT));
586             }
587         } else {
588             Object object = isValid.left().value();
589             if (object != null) {
590                 newValue = object.toString();
591             }
592         }
593         ImmutablePair<String, Boolean> pair = validateAndUpdateRules(propertyType, property.getRules(), updatedInnerType, allDataTypes, isValidate);
594         log.trace("After validateAndUpdateRules. pair = {}", pair);
595         if (Boolean.FALSE.equals(pair.getRight())) {
596             BeEcompErrorManager.getInstance().logBeInvalidValueError(ADD_PROPERTY_VALUE, pair.getLeft(), property.getName(), propertyType);
597             throw new StorageException(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(
598                     JanusGraphOperationStatus.ILLEGAL_ARGUMENT));
599         }
600         return newValue;
601     }
602
603     private String updateInnerType(IPropertyInputCommon property) {
604         ToscaPropertyType type = ToscaPropertyType.isValidType(property.getType());
605         if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
606             SchemaDefinition def = property.getSchema();
607             if (def == null) {
608                 log.debug(SCHEMA_DOESN_T_EXISTS_FOR_PROPERTY_OF_TYPE, type);
609                 failOnIllegalArgument();
610             }
611             PropertyDataDefinition propDef = def.getProperty();
612             if (propDef == null) {
613                 log.debug(PROPERTY_IN_SCHEMA_DEFINITION_INSIDE_PROPERTY_OF_TYPE_DOESN_T_EXIST, type);
614                 failOnIllegalArgument();
615             }
616             return propDef.getType();
617         }
618         return null;
619     }
620
621     private void failOnIllegalArgument() {
622         throw new ByActionStatusComponentException(
623                 componentsUtils.convertFromStorageResponse(
624                         DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT)));
625     }
626
627     public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, boolean isValidate, String innerType, Map<String, DataTypeDefinition> dataTypes) {
628         log.trace("Going to validate property value and its type. type = {}, value = {}", propertyType, value);
629         ToscaPropertyType type = getType(propertyType);
630
631         if (isValidate) {
632
633             if (type == null) {
634                 DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
635                 ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, dataTypes);
636                 if (Boolean.FALSE.equals(validateResult.right)) {
637                     log.debug(THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID, value, propertyType);
638                     return Either.right(false);
639                 }
640                 JsonElement jsonElement = validateResult.left;
641                 String valueFromJsonElement = getValueFromJsonElement(jsonElement);
642                 return Either.left(valueFromJsonElement);
643             }
644             log.trace("before validating property type {}", propertyType);
645             boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
646             if (!isValidProperty) {
647                 log.debug(THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID, value, type);
648                 return Either.right(false);
649             }
650         }
651         Object convertedValue = value;
652         if (!isEmptyValue(value) && isValidate) {
653             PropertyValueConverter converter = type.getConverter();
654             convertedValue = converter.convert(value, innerType, dataTypes);
655         }
656         return Either.left(convertedValue);
657     }
658
659     private ImmutablePair<String, Boolean> validateAndUpdateRules(String propertyType, List<PropertyRule> rules, String innerType, Map<String, DataTypeDefinition> dataTypes, boolean isValidate) {
660
661         if (rules == null || rules.isEmpty()) {
662             return ImmutablePair.of(null, true);
663         }
664
665         for (PropertyRule rule : rules) {
666             String value = rule.getValue();
667             Either<Object, Boolean> updateResult = validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, dataTypes);
668             if (updateResult.isRight()) {
669                 Boolean status = updateResult.right().value();
670                 if (Boolean.FALSE.equals(status)) {
671                     return ImmutablePair.of(value, status);
672                 }
673             } else {
674                 String newValue = null;
675                 Object object = updateResult.left().value();
676                 if (object != null) {
677                     newValue = object.toString();
678                 }
679                 rule.setValue(newValue);
680             }
681         }
682
683         return ImmutablePair.of(null, true);
684     }
685
686     protected boolean isValidValue(ToscaPropertyType type, String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
687         if (isEmptyValue(value)) {
688             return true;
689         }
690
691         PropertyTypeValidator validator = type.getValidator();
692
693         return validator.isValid(value, innerType, dataTypes);
694     }
695
696     public boolean isEmptyValue(String value) {
697         return value == null;
698     }
699
700     protected String getValueFromJsonElement(JsonElement jsonElement) {
701         if (jsonElement == null || jsonElement.isJsonNull()) {
702             return EMPTY_VALUE;
703         }
704         if (jsonElement.toString().isEmpty()) {
705             return "";
706         }
707         return jsonElement.toString();
708     }
709
710     protected void rollbackWithException(ActionStatus actionStatus, String... params) {
711         janusGraphDao.rollback();
712         throw new ByActionStatusComponentException(actionStatus, params);
713     }
714
715     public  <T extends ToscaDataDefinition> Either<List<T>, ResponseFormat> declareProperties(String userId, String componentId,
716                                                                                               ComponentTypeEnum componentTypeEnum, ComponentInstInputsMap componentInstInputsMap) {
717
718         return Either.left(new ArrayList<>());
719     }
720
721     public <T extends PropertyDataDefinition> List<PropertyConstraint> setInputConstraint(T inputDefinition) {
722         if (StringUtils.isNotBlank(inputDefinition.getParentPropertyType())
723                 && StringUtils.isNotBlank(inputDefinition.getSubPropertyInputPath())) {
724             return setConstraint(inputDefinition);
725         }
726
727         return Collections.emptyList();
728     }
729
730     private <T extends PropertyDataDefinition> List<PropertyConstraint> setConstraint(T inputDefinition) {
731         List<PropertyConstraint> constraints = new ArrayList<>();
732         String[] inputPathArr = inputDefinition.getSubPropertyInputPath().split("#");
733         if (inputPathArr.length > 1) {
734             inputPathArr = ArrayUtils.remove(inputPathArr, 0);
735         }
736
737         Map<String, DataTypeDefinition> dataTypeDefinitionMap =
738                 applicationDataTypeCache.getAll().left().value();
739
740         String propertyType = inputDefinition.getParentPropertyType();
741
742         for (String anInputPathArr : inputPathArr) {
743             if (ToscaType.isPrimitiveType(propertyType)) {
744                 constraints.addAll(
745                         dataTypeDefinitionMap.get(propertyType).getConstraints());
746             } else if (!ToscaType.isCollectionType(propertyType)) {
747                 propertyType = setConstraintForComplexType(dataTypeDefinitionMap, propertyType, anInputPathArr,
748                         constraints);
749             }
750         }
751
752         return constraints;
753     }
754
755     private String setConstraintForComplexType(Map<String, DataTypeDefinition> dataTypeDefinitionMap,
756                                                String propertyType,
757                                                String anInputPathArr,
758                                                List<PropertyConstraint> constraints) {
759         String type = null;
760         List<PropertyDefinition> propertyDefinitions =
761                 dataTypeDefinitionMap.get(propertyType).getProperties();
762         for (PropertyDefinition propertyDefinition : propertyDefinitions) {
763             if (propertyDefinition.getName().equals(anInputPathArr)) {
764                 if (ToscaType.isPrimitiveType(propertyDefinition.getType())) {
765                     constraints.addAll(propertyDefinition.safeGetConstraints());
766                 } else {
767                     type = propertyDefinition.getType();
768                 }
769                 break;
770             }
771         }
772
773         return type;
774     }
775
776
777     protected void rollbackWithException(StorageException e) {
778         janusGraphDao.rollback();
779         throw e;
780     }
781
782     protected void rollbackWithException(ComponentException e) {
783         janusGraphDao.rollback();
784         throw e;
785     }
786
787     protected void unlockRollbackWithException(Component component, RuntimeException e) {
788         janusGraphDao.rollback();
789         graphLockOperation.unlockComponent(component.getUniqueId(), component.getComponentType().getNodeType());
790         throw e;
791     }
792
793     protected void unlockWithCommit(Component component){
794         ComponentTypeEnum componentType = component.getComponentType();
795         NodeTypeEnum nodeType = componentType.getNodeType();
796         janusGraphDao.commit();
797         graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
798     }
799
800     protected ComponentInstance componentInstanceException(StorageOperationStatus storageOperationStatus) {
801         throw new StorageException(storageOperationStatus);
802     }
803
804     protected Component componentException(StorageOperationStatus storageOperationStatus) {
805         throw new StorageException(storageOperationStatus);
806     }
807
808     protected PolicyDefinition storageExceptionPolicyDefinition(StorageOperationStatus storageOperationStatus) {
809         throw new StorageException(storageOperationStatus);
810     }
811
812     protected PolicyDefinition componentExceptionPolicyDefinition(ResponseFormat responseFormat) {
813         throw new ByResponseFormatComponentException(responseFormat);
814     }
815
816     protected Component componentException(ResponseFormat responseFormat) {
817         throw new ByResponseFormatComponentException(responseFormat);
818     }
819
820     protected List<ComponentInstanceProperty> componentInstancePropertyListException(StorageOperationStatus storageOperationStatus) {
821         throw new StorageException(storageOperationStatus);
822     }
823
824 }