2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.be.components.impl;
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;
64 import java.util.Arrays;
65 import java.util.List;
67 import java.util.function.Function;
69 public abstract class BaseBusinessLogic {
71 private static final String FAILED_TO_LOCK_COMPONENT_ERROR = "Failed to lock component {} error - {}";
73 private static final Logger log = Logger.getLogger(BaseBusinessLogic.class.getName());
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";
80 protected ComponentsUtils componentsUtils;
83 protected IUserBusinessLogic userAdmin;
86 protected IGraphLockOperation graphLockOperation;
89 protected TitanDao titanDao;
92 protected TitanGenericDao titanGenericDao;
95 protected IElementOperation elementDao;
98 protected IGroupOperation groupOperation;
101 IGroupInstanceOperation groupInstanceOperation;
104 protected IGroupTypeOperation groupTypeOperation;
107 protected GroupBusinessLogic groupBusinessLogic;
110 PolicyTypeOperation policyTypeOperation;
112 @javax.annotation.Resource
113 protected ArtifactsOperations artifactToscaOperation;
116 protected PropertyOperation propertyOperation;
119 protected ApplicationDataTypeCache applicationDataTypeCache;
122 protected ToscaOperationFacade toscaOperationFacade;
125 protected ApplicationDataTypeCache dataTypeCache;
128 protected InterfaceOperation interfaceOperation;
131 protected InterfaceOperationBusinessLogic interfaceOperationBusinessLogic;
134 protected InterfaceLifecycleOperation interfaceLifecycleOperation;
136 @javax.annotation.Resource
137 private UserValidations userValidations;
139 DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
142 public void setUserAdmin(UserBusinessLogic userAdmin) {
143 this.userAdmin = userAdmin;
146 public void setUserValidations(UserValidations userValidations) {
147 this.userValidations = userValidations;
150 public void setComponentsUtils(ComponentsUtils componentsUtils) {
151 this.componentsUtils = componentsUtils;
154 public void setGraphLockOperation(IGraphLockOperation graphLockOperation) {
155 this.graphLockOperation = graphLockOperation;
158 public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
159 this.toscaOperationFacade = toscaOperationFacade;
162 public void setDataTypeCache(ApplicationDataTypeCache dataTypeCache) {
163 this.dataTypeCache = dataTypeCache;
166 public void setPropertyOperation(PropertyOperation propertyOperation) {
167 this.propertyOperation = propertyOperation;
170 public void setInterfaceOperation(InterfaceOperation interfaceOperation) {
171 this.interfaceOperation = interfaceOperation;
173 public void setInterfaceOperationBusinessLogic(InterfaceOperationBusinessLogic interfaceOperationBusinessLogic) {
174 this.interfaceOperationBusinessLogic = interfaceOperationBusinessLogic;
178 public void setInterfaceLifecycleOperation(InterfaceLifecycleOperation interfaceLifecycleOperation) {
179 this.interfaceLifecycleOperation = interfaceLifecycleOperation;
182 User validateUserNotEmpty(User user, String ecompErrorContext) {
183 return userValidations.validateUserNotEmpty(user, ecompErrorContext);
186 protected User validateUserExists(User user, String ecompErrorContext, boolean inTransaction) {
187 return userValidations.validateUserExists(user.getUserId(), ecompErrorContext, inTransaction);
190 void validateUserExist(String userId, String ecompErrorContext) {
191 userValidations.validateUserExist(userId, ecompErrorContext);
194 Either<User, ActionStatus> validateUserExistsActionStatus(String userId, String ecompErrorContext) {
195 return userValidations.validateUserExistsActionStatus(userId, ecompErrorContext);
198 public User validateUserExists(String userId, String ecompErrorContext, boolean inTransaction) {
199 return userValidations.validateUserExists(userId, ecompErrorContext, inTransaction);
202 protected void validateUserRole(User user, List<Role> roles) {
203 userValidations.validateUserRole(user, roles);
206 protected Either<Boolean, ResponseFormat> lockComponent(Component component, String ecompErrorContext) {
207 return lockComponent(component.getUniqueId(), component, ecompErrorContext);
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);
215 protected Either<Boolean, ResponseFormat> lockComponent(String componentId, Component component, String ecompErrorContext) {
216 return lockElement( componentId, component, ecompErrorContext)
218 .map(r -> logAndConvertError(r, component.getUniqueId(), component.getName()) );
221 protected void lockComponent(String componentId, Component component, boolean needLock, String ecompErrorContext) {
223 lockElement( componentId, component, ecompErrorContext)
225 .on(r -> logAndThrowException(r, component.getUniqueId(), component.getName()) );
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);
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;
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);
245 if (lockResourceStatus.equals(StorageOperationStatus.OK)) {
246 return Either.left(true);
248 BeEcompErrorManager.getInstance().logBeFailedLockObjectError(ecompErrorContext, nodeType.getName(), componentId);
249 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(lockResourceStatus, componentType);
250 return Either.right(actionStatus);
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()) {
265 graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
268 protected void unlockComponent(Either<?, ?> either, Component component) {
269 unlockComponent(either, component, false);
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);
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));
283 return Either.left(true);
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));
293 return Either.left(componentTypeEnum);
297 protected Either<Component, ResponseFormat> validateComponentExists(String componentId, ComponentTypeEnum componentType, ComponentParametersView filter) {
298 return toscaOperationFacade.getToscaElement(componentId, filter == null ? new ComponentParametersView() : filter)
300 .map(err -> handleGetComponentError(componentId, componentType, err))
302 .bind(cmpt -> validateComponentType(cmpt, componentType));
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));
311 return Either.left(cmpt);
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))));
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))));
333 Object object = isValid.left().value();
334 if (object != null) {
335 newValue = object.toString();
338 return Either.left(newValue);
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));
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));
355 innerType = innerProperty.getType();
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());
367 // verify userId is not null
368 if (userId == null) {
369 log.debug("Current user userId is null");
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);
380 // verify resource is not deleted
381 if (Boolean.TRUE.equals(component.getIsDeleted())) {
382 log.debug("Component {} is marked as deleted", component.getUniqueId());
386 return Either.left(true);
389 ComponentTypeEnum getComponentTypeByParentComponentType(ComponentTypeEnum parentComponentType) {
390 switch (parentComponentType) {
392 return ComponentTypeEnum.RESOURCE;
394 return ComponentTypeEnum.RESOURCE;
396 return ComponentTypeEnum.SERVICE;
404 public void setTitanGenericDao(TitanDao titanDao) {
405 this.titanDao = titanDao;
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));
416 BeEcompErrorManager.getInstance().logInternalFlowError("FetchDataTypes", "Failed to fetch data types", ErrorSeverity.ERROR);
417 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
420 return Either.left(allDataTypes.left().value());
423 Either<Boolean, ResponseFormat> validatePropertyDefaultValue(IComplexDefaultValue property, Map<String, DataTypeDefinition> dataTypes) {
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);
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);
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());
447 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEFAULT_VALUE, property.getName(), type, property.getDefaultValue());
449 return Either.right(responseFormat);
452 return Either.left(true);
456 void handleDefaultValue(IComplexDefaultValue newAttributeDef, Map<String, DataTypeDefinition> dataTypes) {
458 ToscaPropertyType type = ToscaPropertyType.isValidType(newAttributeDef.getType());
459 PropertyValueConverter converter = type.getConverter();
461 String innerType = null;
463 SchemaDefinition schema = newAttributeDef.getSchema();
464 if (schema != null) {
465 PropertyDataDefinition prop = schema.getProperty();
466 if (schema.getProperty() != null) {
467 innerType = prop.getType();
470 String convertedValue;
471 if (newAttributeDef.getDefaultValue() != null) {
472 convertedValue = converter.convert(newAttributeDef.getDefaultValue(), innerType, dataTypes);
473 newAttributeDef.setDefaultValue(convertedValue);
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));
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));
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)));
502 protected ToscaPropertyType getType(String propertyType) {
503 return ToscaPropertyType.isValidType(propertyType);
506 void commitOrRollback(Either<?, ResponseFormat> result) {
507 if (result == null || result.isRight()) {
508 log.warn("operation failed. do rollback");
511 log.debug("operation success. do commit");
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);
521 if (lockResourceStatus.equals(StorageOperationStatus.OK)) {
522 return Either.left(true);
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);
532 protected Either<Component, ResponseFormat> validateComponentExistsByFilter(String componentId, ComponentTypeEnum componentType, ComponentParametersView componentParametersView) {
533 return toscaOperationFacade.getToscaElement(componentId, componentParametersView)
535 .map(err -> handleGetComponentError(componentId, componentType, err));
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;
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);
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));
563 Object object = isValid.left().value();
564 if (object != null) {
565 newValue = object.toString();
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));
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();
582 log.debug(SCHEMA_DOESN_T_EXISTS_FOR_PROPERTY_OF_TYPE, type);
583 failOnIllegalArgument();
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();
590 return propDef.getType();
595 private void failOnIllegalArgument() {
596 throw new ComponentException(
597 componentsUtils.convertFromStorageResponse(
598 DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT)));
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);
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);
614 JsonElement jsonElement = validateResult.left;
615 String valueFromJsonElement = getValueFromJsonElement(jsonElement);
616 return Either.left(valueFromJsonElement);
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);
625 Object convertedValue = value;
626 if (!isEmptyValue(value) && isValidate) {
627 PropertyValueConverter converter = type.getConverter();
628 convertedValue = converter.convert(value, innerType, dataTypes);
630 return Either.left(convertedValue);
633 private ImmutablePair<String, Boolean> validateAndUpdateRules(String propertyType, List<PropertyRule> rules, String innerType, Map<String, DataTypeDefinition> dataTypes, boolean isValidate) {
635 if (rules == null || rules.isEmpty()) {
636 return ImmutablePair.of(null, true);
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);
648 String newValue = null;
649 Object object = updateResult.left().value();
650 if (object != null) {
651 newValue = object.toString();
653 rule.setValue(newValue);
657 return ImmutablePair.of(null, true);
660 protected boolean isValidValue(ToscaPropertyType type, String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
661 if (isEmptyValue(value)) {
665 PropertyTypeValidator validator = type.getValidator();
667 return validator.isValid(value, innerType, dataTypes);
670 public boolean isEmptyValue(String value) {
671 return value == null;
674 protected String getValueFromJsonElement(JsonElement jsonElement) {
675 if (jsonElement == null || jsonElement.isJsonNull()) {
678 if (jsonElement.toString().isEmpty()) {
681 return jsonElement.toString();
684 protected void rollbackWithException(ActionStatus actionStatus, String... params) {
686 throw new ComponentException(actionStatus, params);