[SDC] rebase 1710 code
[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 java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.function.Function;
28
29 import org.apache.commons.lang3.StringUtils;
30 import org.apache.commons.lang3.tuple.ImmutablePair;
31 import org.openecomp.sdc.be.config.BeEcompErrorManager;
32 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
33 import org.openecomp.sdc.be.dao.api.ActionStatus;
34 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
35 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
36 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
37 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
38 import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
39 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
40 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
41 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
42 import org.openecomp.sdc.be.impl.ComponentsUtils;
43 import org.openecomp.sdc.be.model.Component;
44 import org.openecomp.sdc.be.model.ComponentInstanceInput;
45 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
46 import org.openecomp.sdc.be.model.ComponentParametersView;
47 import org.openecomp.sdc.be.model.DataTypeDefinition;
48 import org.openecomp.sdc.be.model.GroupProperty;
49 import org.openecomp.sdc.be.model.IComplexDefaultValue;
50 import org.openecomp.sdc.be.model.IPropertyInputCommon;
51 import org.openecomp.sdc.be.model.LifecycleStateEnum;
52 import org.openecomp.sdc.be.model.User;
53 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
54 import org.openecomp.sdc.be.model.jsontitan.operations.ArtifactsOperations;
55 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
56 import org.openecomp.sdc.be.model.operations.api.IAttributeOperation;
57 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
58 import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
59 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
60 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
61 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
62 import org.openecomp.sdc.be.model.operations.api.IPropertyOperation;
63 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
64 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
65 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
66 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
67 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
68 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
69 import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter;
70 import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
71 import org.openecomp.sdc.be.resources.data.PropertyValueData;
72 import org.openecomp.sdc.be.user.IUserBusinessLogic;
73 import org.openecomp.sdc.be.user.Role;
74 import org.openecomp.sdc.be.user.UserBusinessLogic;
75 import org.openecomp.sdc.common.api.Constants;
76 import org.openecomp.sdc.common.datastructure.Wrapper;
77 import org.openecomp.sdc.common.util.ValidationUtils;
78 import org.openecomp.sdc.exception.ResponseFormat;
79 import org.slf4j.Logger;
80 import org.slf4j.LoggerFactory;
81 import org.springframework.beans.factory.annotation.Autowired;
82
83 import com.google.gson.JsonElement;
84
85 import fj.data.Either;
86
87 public abstract class BaseBusinessLogic {
88
89         @Autowired
90         protected ComponentsUtils componentsUtils;
91
92         @Autowired
93         protected IUserBusinessLogic userAdmin;
94
95         @Autowired
96         protected IGraphLockOperation graphLockOperation;
97
98         @Autowired
99         protected TitanDao titanDao;
100         
101         @Autowired
102         protected TitanGenericDao titanGenericDao;
103
104         @Autowired
105         protected IElementOperation elementDao;
106
107         @Autowired
108         protected IGroupOperation groupOperation;
109         
110         @Autowired
111         protected IGroupInstanceOperation groupInstanceOperation;
112
113         @Autowired
114         protected IGroupTypeOperation groupTypeOperation;
115
116         /*@Autowired
117         protected IArtifactOperation artifactOperation;*/
118         @javax.annotation.Resource
119         protected ArtifactsOperations artifactToscaOperation;
120
121 //      @Autowired
122 //      protected IAttributeOperation attributeOperation;
123
124         @Autowired
125         protected PropertyOperation propertyOperation;
126
127         @Autowired
128         protected ApplicationDataTypeCache applicationDataTypeCache;
129
130         @Autowired
131         protected ToscaOperationFacade toscaOperationFacade; 
132         
133         protected DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
134
135         public void setUserAdmin(UserBusinessLogic userAdmin) {
136                 this.userAdmin = userAdmin;
137         }
138
139         public void setComponentsUtils(ComponentsUtils componentsUtils) {
140                 this.componentsUtils = componentsUtils;
141         }
142
143         public void setGraphLockOperation(IGraphLockOperation graphLockOperation) {
144                 this.graphLockOperation = graphLockOperation;
145         }
146
147         public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
148                 this.toscaOperationFacade = toscaOperationFacade;
149         }
150
151
152         private static Logger log = LoggerFactory.getLogger(BaseBusinessLogic.class.getName());
153         
154         public static final String EMPTY_VALUE = null;
155
156         protected Either<User, ResponseFormat> validateUserNotEmpty(User user, String ecompErrorContext) {
157                 String userId = user.getUserId();
158
159                 if (StringUtils.isEmpty(userId)) {
160                         log.debug("User header is missing ");
161                         BeEcompErrorManager.getInstance().logBeUserMissingError(ecompErrorContext, user.getUserId());
162                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION);
163                         return Either.right(responseFormat);
164                 }
165                 return Either.left(user);
166         }
167
168         protected Either<User, ResponseFormat> validateUserExists(User user, String ecompErrorContext, boolean inTransaction) {
169                 return validateUserExists(user.getUserId(), ecompErrorContext, inTransaction);
170         }
171
172         protected void validateUserExist(String userId, String ecompErrorContext, Wrapper<ResponseFormat> errorWrapper) {
173                 Either<User, ResponseFormat> resp = validateUserExists(userId, ecompErrorContext, false);
174                 if (resp.isRight()) {
175                         errorWrapper.setInnerElement(resp.right().value());
176                 }
177         }
178
179         public Either<User, ActionStatus> validateUserExistsActionStatus(String userId, String ecompErrorContext) {
180                 Either<User, ActionStatus> eitherCreator = userAdmin.getUser(userId, false);
181                 if (eitherCreator.isRight() || eitherCreator.left().value() == null) {
182                         if (eitherCreator.right().value().equals(ActionStatus.USER_NOT_FOUND)) {
183                                 log.debug("validateUserExists - not authorized user, userId {}", userId);
184                                 Either.right(ActionStatus.RESTRICTED_OPERATION);
185                         } else {
186                                 log.debug("validateUserExists - failed to authorize user, userId {}", userId);
187                         }
188                         log.debug("User is not listed. userId {}", userId);
189                         BeEcompErrorManager.getInstance().logBeUserMissingError(ecompErrorContext, userId);
190                         return Either.right(eitherCreator.right().value());
191                 }
192                 return Either.left(eitherCreator.left().value());
193         }
194
195         public Either<User, ResponseFormat> validateUserExists(String userId, String ecompErrorContext, boolean inTransaction) {
196                 Either<User, ActionStatus> eitherCreator = userAdmin.getUser(userId, inTransaction);
197                 if (eitherCreator.isRight() || eitherCreator.left().value() == null) {
198                         ResponseFormat responseFormat;
199                         if (eitherCreator.right().value().equals(ActionStatus.USER_NOT_FOUND)) {
200                                 if (log.isDebugEnabled())
201                                         log.debug("validateUserExists - not authorized user, userId {}", userId);
202                                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
203                         } else {
204                                 if (log.isDebugEnabled())
205                                         log.debug("validateUserExists - failed to authorize user, userId {}", userId);
206                                 responseFormat = componentsUtils.getResponseFormat(eitherCreator.right().value());
207                         }
208                         if (log.isDebugEnabled())
209                                 log.debug("User is not listed. userId {}", userId);
210                         BeEcompErrorManager.getInstance().logBeUserMissingError(ecompErrorContext, userId);
211                         return Either.right(responseFormat);
212                 }
213                 return Either.left(eitherCreator.left().value());
214         }
215
216         protected Either<Boolean, ResponseFormat> validateUserRole(User user, List<Role> roles) {
217                 Role userRole = Role.valueOf(user.getRole());
218                 if (roles != null) {
219                         if (!roles.contains(userRole)) {
220                                 if (log.isDebugEnabled())
221                                         log.debug("user is not in appropriate role to perform action");
222                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
223                                 return Either.right(responseFormat);
224                         }
225                         return Either.left(Boolean.TRUE);
226                 }
227                 return Either.left(Boolean.FALSE);
228         }
229
230         protected Either<Boolean, ResponseFormat> lockComponent(Component component, String ecompErrorContext) {
231                 return lockComponent(component.getUniqueId(), component, ecompErrorContext);
232         }
233
234         protected Either<Boolean, ResponseFormat> lockComponent(String componentId, Component component, String ecompErrorContext) {
235                 ComponentTypeEnum componentType = component.getComponentType();
236                 NodeTypeEnum nodeType = componentType.getNodeType();
237                 StorageOperationStatus lockResourceStatus = graphLockOperation.lockComponent(componentId, nodeType);
238
239                 if (lockResourceStatus.equals(StorageOperationStatus.OK)) {
240                         return Either.left(true);
241                 } else {
242                         BeEcompErrorManager.getInstance().logBeFailedLockObjectError(ecompErrorContext, nodeType.getName(), componentId);
243                         ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(lockResourceStatus, componentType);
244                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, component.getName());
245                         log.debug("Failed to lock component {} error - {}" ,componentId, actionStatus);
246                         return Either.right(responseFormat);
247                 }
248         }
249
250         protected void unlockComponent(Either<?, ?> either, Component component, boolean inTransaction) {
251                 ComponentTypeEnum componentType = component.getComponentType();
252                 NodeTypeEnum nodeType = componentType.getNodeType();
253                 if (false == inTransaction) {
254                         if (either == null || either.isRight()) {
255                                 titanDao.rollback();
256                         } else {
257                                 titanDao.commit();
258                         }
259                 }
260                 // unlock resource
261                 graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
262         }
263
264         protected void unlockComponent(Either<?, ?> either, Component component) {
265                 unlockComponent(either, component, false);
266         }
267
268         protected <T> Either<Boolean, ResponseFormat> validateJsonBody(T bodyObject, Class<T> clazz) {
269                 if (bodyObject == null) {
270                         log.debug("Invalid JSON received for object of type {}", clazz.getSimpleName());
271                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
272                 } else {
273                         return Either.left(true);
274                 }
275         }
276
277         protected Either<ComponentTypeEnum, ResponseFormat> validateComponentType(String componentType) {
278                 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
279                 if (componentTypeEnum == null) {
280                         log.debug("Invalid component type {}", componentType);
281                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, componentType));
282                 } else {
283                         return Either.left(componentTypeEnum);
284                 }
285         }
286
287         protected Either<Component, ResponseFormat> validateComponentExists(String componentId, ComponentTypeEnum componentType, ComponentParametersView filter) {
288                 
289                 if(filter == null){
290                         filter = new ComponentParametersView();
291                 }
292                 Either<Component, StorageOperationStatus> componentFound  = toscaOperationFacade.getToscaElement(componentId, filter);
293                 if (componentFound.isRight()) {
294                         StorageOperationStatus storageOperationStatus = componentFound.right().value();
295                         ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageOperationStatus, componentType);
296                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, Constants.EMPTY_STRING);
297                         log.debug("Component with id {} was not found", componentId);
298                         return Either.right(responseFormat);
299                 }
300                 return Either.left(componentFound.left().value());
301         }
302
303 //      protected Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponentExists(String componentId, ComponentTypeEnum componentType, ComponentParametersView componentParametersView, String userId,
304 //                      AuditingActionEnum auditingAction, User user) {
305 //
306 //              ComponentOperation componentOperation = getComponentOperation(componentType);
307 //
308 //              if (componentOperation == null) {
309 //                      ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
310 //                      log.debug("addGroup - not supported component type {}", componentType);
311 //                      return Either.right(responseFormat);
312 //              }
313 //              Either<? extends org.openecomp.sdc.be.model.Component, StorageOperationStatus> componentResult = componentOperation.getComponent(componentId, componentParametersView, true);
314 //
315 //              if (componentResult.isRight()) {
316 //                      ActionStatus status = (componentType.equals(ComponentTypeEnum.RESOURCE)) ? ActionStatus.RESOURCE_NOT_FOUND : ActionStatus.SERVICE_NOT_FOUND;
317 //
318 //                      ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, componentId);
319 //
320 //                      log.debug("Service not found, serviceId {}", componentId);
321 //                      // ComponentTypeEnum componentForAudit =
322 //                      // (componentType.equals(ComponentTypeEnum.RESOURCE)) ?
323 //                      // ComponentTypeEnum.RESOURCE : ComponentTypeEnum.SERVICE;
324 //                      // handleAuditing(auditingAction, null, componentId, user, null,
325 //                      // null, artifactId, responseFormat, componentForAudit, null);
326 //                      return Either.right(responseFormat);
327 //              }
328 //              return Either.left(componentResult.left().value());
329 //      }
330
331         public Either<Boolean, ResponseFormat> validateCanWorkOnComponent(Component component, String userId) {
332                 Either<Boolean, ResponseFormat> canWork = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
333                 if (component.getLifecycleState() != LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) {
334                         log.debug("Component {} is not checked-out", component.getName());
335                         return canWork;
336                 }
337
338                 // verify userId is not null
339                 if (userId == null) {
340                         log.debug("Current user userId is null");
341                         return canWork;
342                 }
343
344                 // verify component last update user is the current user
345                 String lastUpdaterUserId = component.getLastUpdaterUserId();
346                 if (!userId.equals(lastUpdaterUserId)) {
347                         log.debug("Current user is not last updater, last updater userId: {}, current user userId: {}", lastUpdaterUserId, userId);
348                         return canWork;
349                 }
350
351                 // verify resource is not deleted
352                 if ((component.getIsDeleted() != null) && (component.getIsDeleted() == true)) {
353                         log.debug("Component {} is marked as deleted", component.getUniqueId());
354                         return canWork;
355                 }
356
357                 return Either.left(true);
358         }
359
360         public ComponentTypeEnum getComponentTypeByParentComponentType(ComponentTypeEnum parentComponentType) {
361                 switch (parentComponentType) {
362                 case SERVICE:
363                         return ComponentTypeEnum.RESOURCE;
364                 case RESOURCE:
365                         return ComponentTypeEnum.RESOURCE;
366                 case PRODUCT:
367                         return ComponentTypeEnum.SERVICE;
368                 default:
369                         break;
370                 }
371                 return null;
372         }
373
374         // For UT
375         public void setTitanGenericDao(TitanDao titanDao) {
376                 this.titanDao = titanDao;
377         }
378
379         protected Either<Map<String, DataTypeDefinition>, ResponseFormat> getAllDataTypes(ApplicationDataTypeCache applicationDataTypeCache) {
380                 Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = applicationDataTypeCache.getAll();
381                 if (allDataTypes.isRight()) {
382                         TitanOperationStatus operationStatus = allDataTypes.right().value();
383                         if (operationStatus == TitanOperationStatus.NOT_FOUND) {
384                                 BeEcompErrorManager.getInstance().logInternalDataError("FetchDataTypes", "Data types are not loaded", ErrorSeverity.ERROR);
385                                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.DATA_TYPE_CANNOT_BE_EMPTY));
386                         } else {
387                                 BeEcompErrorManager.getInstance().logInternalFlowError("FetchDataTypes", "Failed to fetch data types", ErrorSeverity.ERROR);
388                                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
389                         }
390                 }
391                 return Either.left(allDataTypes.left().value());
392         }
393
394         protected Either<Boolean, ResponseFormat> validatePropertyDefaultValue(IComplexDefaultValue property, Map<String, DataTypeDefinition> dataTypes) {
395                 String type = null;
396                 String innerType = null;
397                 if (!propertyOperation.isPropertyTypeValid(property)) {
398                         log.info("Invalid type for property {} type {}", property.getName(), property.getType());
399                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_TYPE, property.getType(), property.getName());
400                         return Either.right(responseFormat);
401                 }
402                 type = property.getType();
403                 if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
404                         ImmutablePair<String, Boolean> propertyInnerTypeValid = propertyOperation.isPropertyInnerTypeValid(property, dataTypes);
405                         innerType = propertyInnerTypeValid.getLeft();
406                         if (!propertyInnerTypeValid.getRight().booleanValue()) {
407                                 log.info("Invalid inner type for property {} type {}", property.getName(), property.getType() );
408                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE, innerType, property.getName());
409                                 return Either.right(responseFormat);
410                         }
411                 }
412                 if (!propertyOperation.isPropertyDefaultValueValid(property, dataTypes)) {
413                         log.info("Invalid default value for property {} type {}", property.getName(), property.getType() );
414                         ResponseFormat responseFormat;
415                         if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
416                                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE, property.getName(), type, innerType, property.getDefaultValue());
417                         } else {
418                                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEFAULT_VALUE, property.getName(), type, property.getDefaultValue());
419                         }
420                         return Either.right(responseFormat);
421
422                 }
423                 return Either.left(true);
424         }
425
426 //      protected Either<Resource, StorageOperationStatus> getResource(final String resourceId) {
427 //
428 //              log.debug("Get resource with id {}", resourceId);
429 //              Either<Resource, StorageOperationStatus> status = resourceOperation.getResource(resourceId);
430 //              if (status.isRight()) {
431 //                      log.debug("Resource with id {} was not found", resourceId);
432 //                      return Either.right(status.right().value());
433 //              }
434 //
435 //              Resource resource = status.left().value();
436 //              if (resource == null) {
437 //                      BeEcompErrorManager.getInstance().logBeComponentMissingError("Property Business Logic", ComponentTypeEnum.RESOURCE.getValue(), resourceId);
438 //                      log.debug("General Error while get resource with id {}", resourceId);
439 //                      return Either.right(StorageOperationStatus.GENERAL_ERROR);
440 //              }
441 //              return Either.left(resource);
442 //      }
443
444         protected 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                 if (newAttributeDef != null) {
452                         SchemaDefinition schema = newAttributeDef.getSchema();
453                         if (schema != null) {
454                                 PropertyDataDefinition prop = schema.getProperty();
455                                 if (schema.getProperty() != null) {
456                                         innerType = prop.getType();
457                                 }
458                         }
459                         String convertedValue = null;
460                         if (newAttributeDef.getDefaultValue() != null) {
461                                 convertedValue = converter.convert(newAttributeDef.getDefaultValue(), innerType, dataTypes);
462                                 newAttributeDef.setDefaultValue(convertedValue);
463                         }
464                 }
465         }
466
467         protected void validateComponentTypeEnum(ComponentTypeEnum componentTypeEnum, String errorContext, Wrapper<ResponseFormat> errorWrapper) {
468                 if (componentTypeEnum == null) {
469                         BeEcompErrorManager.getInstance().logInvalidInputError(errorContext, "invalid component type", ErrorSeverity.INFO);
470                         errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
471                 }
472
473         }
474
475         protected void validateCanWorkOnComponent(String componentId, ComponentTypeEnum componentTypeEnum, String userId, Wrapper<ResponseFormat> errorWrapper) {
476                 if (!ComponentValidationUtils.canWorkOnComponent(componentId, toscaOperationFacade, userId)) {
477                         log.info("Restricted operation for user {} on {} {}", userId, componentTypeEnum.getValue(), componentId);
478                         errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
479                 }
480
481         }
482
483         protected void validateComponentLock(String componentId, ComponentTypeEnum componentTypeEnum, Wrapper<ResponseFormat> errorWrapper) {
484                 StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType());
485                 if (lockStatus != StorageOperationStatus.OK) {
486                         log.debug("Failed to lock {} {}", componentTypeEnum.getValue(), componentId);
487                         errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
488                 }
489
490         }
491
492         protected ToscaPropertyType getType(String propertyType) {
493
494                 ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
495
496                 return type;
497
498         }
499
500         protected void commitOrRollback(Either<? extends Object, ResponseFormat> result) {
501                 if (result == null || result.isRight()) {
502                         log.warn("operation failed. do rollback");
503                         titanDao.rollback();
504                 } else {
505                         log.debug("operation success. do commit");
506                         titanDao.commit();
507                 }
508         }
509
510         protected Either<Boolean, ResponseFormat> lockComponentByName(String name, Component component, String ecompErrorContext) {
511                 ComponentTypeEnum componentType = component.getComponentType();
512                 NodeTypeEnum nodeType = componentType.getNodeType();
513                 StorageOperationStatus lockResourceStatus = graphLockOperation.lockComponentByName(name, nodeType);
514
515                 if (lockResourceStatus.equals(StorageOperationStatus.OK)) {
516                         return Either.left(true);
517                 } else {
518                         BeEcompErrorManager.getInstance().logBeFailedLockObjectError(ecompErrorContext, nodeType.getName(), name);
519                         ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(lockResourceStatus, componentType);
520                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, component.getName());
521                         log.debug("Failed to lock component {} error - {}", name, actionStatus);
522                         return Either.right(responseFormat);
523                 }
524         }
525
526         protected Either<Component, ResponseFormat> validateComponentExistsByFilter(String componentId, ComponentTypeEnum componentType, ComponentParametersView componentParametersView, boolean inTransaction) {
527
528                 Either<Component, StorageOperationStatus> componentFound = null;
529                 componentFound = toscaOperationFacade.getToscaElement(componentId, componentParametersView);
530
531                 if (componentFound.isRight()) {
532                         StorageOperationStatus storageOperationStatus = componentFound.right().value();
533                         ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageOperationStatus, componentType);
534                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, Constants.EMPTY_STRING);
535                         log.debug("Component with id {} was not found", componentId);
536                         return Either.right(responseFormat);
537                 }
538                 return Either.left(componentFound.left().value());
539         }
540         
541         protected Either<GroupProperty, ResponseFormat> validateFreeText(GroupProperty groupPropertyToUpdate) {
542
543                 Either<GroupProperty, ResponseFormat> ret;
544                 final String groupTypeValue = groupPropertyToUpdate.getValue();
545                 if (!StringUtils.isEmpty(groupTypeValue)) {
546                         if (!ValidationUtils.validateDescriptionLength(groupTypeValue)) {
547                                 ret = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_DESCRIPTION_EXCEEDS_LIMIT,
548                                                 NodeTypeEnum.Property.getName(),
549                                                 String.valueOf(ValidationUtils.COMPONENT_DESCRIPTION_MAX_LENGTH)));
550                         }
551
552                         else if (!ValidationUtils.validateIsEnglish(groupTypeValue)) {
553                                 ret = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_DESCRIPTION,
554                                                 NodeTypeEnum.Property.getName()));
555                         } else {
556                                 ret = Either.left(groupPropertyToUpdate);
557                         }
558
559                 } else {
560                         ret = Either.left(groupPropertyToUpdate);
561                 }
562                 return ret;
563         }
564         
565         @SuppressWarnings("unchecked")
566         protected <T extends Enum<T>> boolean  enumHasValueFilter(String name, Function<String, T> enumGetter, T... enumValues) {
567                 T enumFound = enumGetter.apply(name);
568                 return Arrays.asList(enumValues).contains(enumFound);
569         }
570         
571         protected Either<String, StorageOperationStatus> validatePropValueBeforeCreate(IPropertyInputCommon property, String value, boolean isValidate, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
572                 String propertyType = property.getType();
573                 ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
574
575                 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
576                         SchemaDefinition def = property.getSchema();
577                         if (def == null) {
578                                 log.debug("Schema doesn't exists for property of type {}", type);
579                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
580                         }
581                         PropertyDataDefinition propDef = def.getProperty();
582                         if (propDef == null) {
583                                 log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
584
585                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
586                         }
587                         innerType = propDef.getType();
588                 }       
589
590                 Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, allDataTypes);
591
592                 String newValue = value;
593                 if (isValid.isRight()) {
594                         Boolean res = isValid.right().value();
595                         if (res == false) {
596                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
597                         }
598                 } else {
599                         Object object = isValid.left().value();
600                         if (object != null) {
601                                 newValue = object.toString();
602                         }
603                 }
604
605                 ImmutablePair<String, Boolean> pair = validateAndUpdateRules(propertyType, property.getRules(), innerType, allDataTypes, isValidate);
606                 log.trace("After validateAndUpdateRules. pair = {}", pair);
607                 if (pair.getRight() != null && pair.getRight() == false) {
608                         BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), property.getName(), propertyType);
609                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
610                 }
611
612                 return Either.left(newValue);
613         }
614         
615         protected Either<String, StorageOperationStatus> validateInputValueBeforeCreate(ComponentInstanceInput property, String value, boolean isValidate, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
616                 String propertyType = property.getType();
617                 ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
618
619                 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
620                         SchemaDefinition def = property.getSchema();
621                         if (def == null) {
622                                 log.debug("Schema doesn't exists for property of type {}", type);
623                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
624                         }
625                         PropertyDataDefinition propDef = def.getProperty();
626                         if (propDef == null) {
627                                 log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
628
629                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
630                         }
631                         innerType = propDef.getType();
632                 }       
633
634                 Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, allDataTypes);
635
636                 String newValue = value;
637                 if (isValid.isRight()) {
638                         Boolean res = isValid.right().value();
639                         if (res == false) {
640                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
641                         }
642                 } else {
643                         Object object = isValid.left().value();
644                         if (object != null) {
645                                 newValue = object.toString();
646                         }
647                 }
648
649                 ImmutablePair<String, Boolean> pair = validateAndUpdateRules(propertyType, property.getRules(), innerType, allDataTypes, isValidate);
650                 log.debug("After validateAndUpdateRules. pair = {}", pair);
651                 if (pair.getRight() != null && pair.getRight() == false) {
652                         BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), property.getName(), propertyType);
653                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
654                 }
655
656                 return Either.left(newValue);
657         }
658         
659         public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, boolean isValidate, String innerType, Map<String, DataTypeDefinition> dataTypes) {
660                 log.trace("Going to validate property value and its type. type = {}, value = {}", propertyType, value);
661                 ToscaPropertyType type = getType(propertyType);
662
663                 if (isValidate) {
664
665                         if (type == null) {
666                                 DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
667                                 ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, dataTypes);
668                                 if (validateResult.right.booleanValue() == false) {
669                                         log.debug("The value {} of property from type {} is invalid", value, propertyType);
670                                         return Either.right(false);
671                                 }
672                                 JsonElement jsonElement = validateResult.left;
673                                 String valueFromJsonElement = getValueFromJsonElement(jsonElement);
674                                 return Either.left(valueFromJsonElement);
675                         }
676                         log.trace("before validating property type {}", propertyType);
677                         boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
678                         if (false == isValidProperty) {
679                                 log.debug("The value {} of property from type {} is invalid", value, type);
680                                 return Either.right(false);
681                         }
682                 }
683                 Object convertedValue = value;
684                 if (false == isEmptyValue(value) && isValidate) {
685                         PropertyValueConverter converter = type.getConverter();
686                         convertedValue = converter.convert(value, innerType, dataTypes);
687                 }
688                 return Either.left(convertedValue);
689         }
690
691         public ImmutablePair<String, Boolean> validateAndUpdateRules(String propertyType, List<PropertyRule> rules, String innerType, Map<String, DataTypeDefinition> dataTypes, boolean isValidate) {
692
693                 if (rules == null || rules.isEmpty() == true) {
694                         return new ImmutablePair<String, Boolean>(null, true);
695                 }
696
697                 for (PropertyRule rule : rules) {
698                         String value = rule.getValue();
699                         Either<Object, Boolean> updateResult = validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, dataTypes);
700                         if (updateResult.isRight()) {
701                                 Boolean status = updateResult.right().value();
702                                 if (status == false) {
703                                         return new ImmutablePair<String, Boolean>(value, status);
704                                 }
705                         } else {
706                                 String newValue = null;
707                                 Object object = updateResult.left().value();
708                                 if (object != null) {
709                                         newValue = object.toString();
710                                 }
711                                 rule.setValue(newValue);
712                         }
713                 }
714
715                 return new ImmutablePair<String, Boolean>(null, true);
716         }
717         
718         protected boolean isValidValue(ToscaPropertyType type, String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
719                 if (isEmptyValue(value)) {
720                         return true;
721                 }
722
723                 PropertyTypeValidator validator = type.getValidator();
724
725                 boolean isValid = validator.isValid(value, innerType, dataTypes);
726                 if (true == isValid) {
727                         return true;
728                 } else {
729                         return false;
730                 }
731
732         }
733
734         public boolean isEmptyValue(String value) {
735                 if (value == null) {
736                         return true;
737                 }
738                 return false;
739         }
740
741         public boolean isNullParam(String value) {
742                 if (value == null) {
743                         return true;
744                 }
745                 return false;
746         }
747
748         public void addRulesToNewPropertyValue(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
749
750                 List<PropertyRule> rules = resourceInstanceProperty.getRules();
751                 if (rules == null) {
752                         PropertyRule propertyRule = buildRuleFromPath(propertyValueData, resourceInstanceProperty, resourceInstanceId);
753                         rules = new ArrayList<>();
754                         rules.add(propertyRule);
755                 } else {
756                         rules = sortRules(rules);
757                 }
758
759                 propertyValueData.setRules(rules);
760         }
761
762         private PropertyRule buildRuleFromPath(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
763                 List<String> path = resourceInstanceProperty.getPath();
764                 // FOR BC. Since old Property values on VFC/VF does not have rules on
765                 // graph.
766                 // Update could be done on one level only, thus we can use this
767                 // operation to avoid migration.
768                 if (path == null || path.isEmpty() == true) {
769                         path = new ArrayList<>();
770                         path.add(resourceInstanceId);
771                 }
772                 PropertyRule propertyRule = new PropertyRule();
773                 propertyRule.setRule(path);
774                 propertyRule.setValue(propertyValueData.getValue());
775                 return propertyRule;
776         }
777
778         private List<PropertyRule> sortRules(List<PropertyRule> rules) {
779
780                 // TODO: sort the rules by size and binary representation.
781                 // (x, y, .+) --> 110 6 priority 1
782                 // (x, .+, z) --> 101 5 priority 2
783
784                 return rules;
785         }
786         
787         protected String getValueFromJsonElement(JsonElement jsonElement) {
788                 String value = null;
789
790                 if (jsonElement == null || jsonElement.isJsonNull()) {
791                         value = EMPTY_VALUE;
792                 } else {
793                         if (jsonElement.toString().isEmpty()) {
794                                 value = "";
795                         } else {
796                                 value = jsonElement.toString();
797                         }
798                 }
799
800                 return value;
801         }
802
803 }