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 java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.List;
27 import java.util.function.Function;
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;
83 import com.google.gson.JsonElement;
85 import fj.data.Either;
87 public abstract class BaseBusinessLogic {
90 protected ComponentsUtils componentsUtils;
93 protected IUserBusinessLogic userAdmin;
96 protected IGraphLockOperation graphLockOperation;
99 protected TitanDao titanDao;
102 protected TitanGenericDao titanGenericDao;
105 protected IElementOperation elementDao;
108 protected IGroupOperation groupOperation;
111 protected IGroupInstanceOperation groupInstanceOperation;
114 protected IGroupTypeOperation groupTypeOperation;
117 protected IArtifactOperation artifactOperation;*/
118 @javax.annotation.Resource
119 protected ArtifactsOperations artifactToscaOperation;
122 // protected IAttributeOperation attributeOperation;
125 protected PropertyOperation propertyOperation;
128 protected ApplicationDataTypeCache applicationDataTypeCache;
131 protected ToscaOperationFacade toscaOperationFacade;
133 protected DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
135 public void setUserAdmin(UserBusinessLogic userAdmin) {
136 this.userAdmin = userAdmin;
139 public void setComponentsUtils(ComponentsUtils componentsUtils) {
140 this.componentsUtils = componentsUtils;
143 public void setGraphLockOperation(IGraphLockOperation graphLockOperation) {
144 this.graphLockOperation = graphLockOperation;
147 public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
148 this.toscaOperationFacade = toscaOperationFacade;
152 private static Logger log = LoggerFactory.getLogger(BaseBusinessLogic.class.getName());
154 public static final String EMPTY_VALUE = null;
156 protected Either<User, ResponseFormat> validateUserNotEmpty(User user, String ecompErrorContext) {
157 String userId = user.getUserId();
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);
165 return Either.left(user);
168 protected Either<User, ResponseFormat> validateUserExists(User user, String ecompErrorContext, boolean inTransaction) {
169 return validateUserExists(user.getUserId(), ecompErrorContext, inTransaction);
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());
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);
186 log.debug("validateUserExists - failed to authorize user, userId {}", userId);
188 log.debug("User is not listed. userId {}", userId);
189 BeEcompErrorManager.getInstance().logBeUserMissingError(ecompErrorContext, userId);
190 return Either.right(eitherCreator.right().value());
192 return Either.left(eitherCreator.left().value());
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);
204 if (log.isDebugEnabled())
205 log.debug("validateUserExists - failed to authorize user, userId {}", userId);
206 responseFormat = componentsUtils.getResponseFormat(eitherCreator.right().value());
208 if (log.isDebugEnabled())
209 log.debug("User is not listed. userId {}", userId);
210 BeEcompErrorManager.getInstance().logBeUserMissingError(ecompErrorContext, userId);
211 return Either.right(responseFormat);
213 return Either.left(eitherCreator.left().value());
216 protected Either<Boolean, ResponseFormat> validateUserRole(User user, List<Role> roles) {
217 Role userRole = Role.valueOf(user.getRole());
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);
225 return Either.left(Boolean.TRUE);
227 return Either.left(Boolean.FALSE);
230 protected Either<Boolean, ResponseFormat> lockComponent(Component component, String ecompErrorContext) {
231 return lockComponent(component.getUniqueId(), component, ecompErrorContext);
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);
239 if (lockResourceStatus.equals(StorageOperationStatus.OK)) {
240 return Either.left(true);
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);
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()) {
261 graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
264 protected void unlockComponent(Either<?, ?> either, Component component) {
265 unlockComponent(either, component, false);
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));
273 return Either.left(true);
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));
283 return Either.left(componentTypeEnum);
287 protected Either<Component, ResponseFormat> validateComponentExists(String componentId, ComponentTypeEnum componentType, ComponentParametersView filter) {
290 filter = new ComponentParametersView();
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);
300 return Either.left(componentFound.left().value());
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) {
306 // ComponentOperation componentOperation = getComponentOperation(componentType);
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);
313 // Either<? extends org.openecomp.sdc.be.model.Component, StorageOperationStatus> componentResult = componentOperation.getComponent(componentId, componentParametersView, true);
315 // if (componentResult.isRight()) {
316 // ActionStatus status = (componentType.equals(ComponentTypeEnum.RESOURCE)) ? ActionStatus.RESOURCE_NOT_FOUND : ActionStatus.SERVICE_NOT_FOUND;
318 // ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, componentId);
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);
328 // return Either.left(componentResult.left().value());
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());
338 // verify userId is not null
339 if (userId == null) {
340 log.debug("Current user userId is null");
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);
351 // verify resource is not deleted
352 if ((component.getIsDeleted() != null) && (component.getIsDeleted() == true)) {
353 log.debug("Component {} is marked as deleted", component.getUniqueId());
357 return Either.left(true);
360 public ComponentTypeEnum getComponentTypeByParentComponentType(ComponentTypeEnum parentComponentType) {
361 switch (parentComponentType) {
363 return ComponentTypeEnum.RESOURCE;
365 return ComponentTypeEnum.RESOURCE;
367 return ComponentTypeEnum.SERVICE;
375 public void setTitanGenericDao(TitanDao titanDao) {
376 this.titanDao = titanDao;
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));
387 BeEcompErrorManager.getInstance().logInternalFlowError("FetchDataTypes", "Failed to fetch data types", ErrorSeverity.ERROR);
388 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
391 return Either.left(allDataTypes.left().value());
394 protected Either<Boolean, ResponseFormat> validatePropertyDefaultValue(IComplexDefaultValue property, Map<String, DataTypeDefinition> dataTypes) {
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);
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);
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());
418 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEFAULT_VALUE, property.getName(), type, property.getDefaultValue());
420 return Either.right(responseFormat);
423 return Either.left(true);
426 // protected Either<Resource, StorageOperationStatus> getResource(final String resourceId) {
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());
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);
441 // return Either.left(resource);
444 protected void handleDefaultValue(IComplexDefaultValue newAttributeDef, Map<String, DataTypeDefinition> dataTypes) {
446 ToscaPropertyType type = ToscaPropertyType.isValidType(newAttributeDef.getType());
447 PropertyValueConverter converter = type.getConverter();
449 String innerType = null;
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();
459 String convertedValue = null;
460 if (newAttributeDef.getDefaultValue() != null) {
461 convertedValue = converter.convert(newAttributeDef.getDefaultValue(), innerType, dataTypes);
462 newAttributeDef.setDefaultValue(convertedValue);
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));
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));
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)));
492 protected ToscaPropertyType getType(String propertyType) {
494 ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
500 protected void commitOrRollback(Either<? extends Object, ResponseFormat> result) {
501 if (result == null || result.isRight()) {
502 log.warn("operation failed. do rollback");
505 log.debug("operation success. do commit");
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);
515 if (lockResourceStatus.equals(StorageOperationStatus.OK)) {
516 return Either.left(true);
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);
526 protected Either<Component, ResponseFormat> validateComponentExistsByFilter(String componentId, ComponentTypeEnum componentType, ComponentParametersView componentParametersView, boolean inTransaction) {
528 Either<Component, StorageOperationStatus> componentFound = null;
529 componentFound = toscaOperationFacade.getToscaElement(componentId, componentParametersView);
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);
538 return Either.left(componentFound.left().value());
541 protected Either<GroupProperty, ResponseFormat> validateFreeText(GroupProperty groupPropertyToUpdate) {
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)));
552 else if (!ValidationUtils.validateIsEnglish(groupTypeValue)) {
553 ret = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_DESCRIPTION,
554 NodeTypeEnum.Property.getName()));
556 ret = Either.left(groupPropertyToUpdate);
560 ret = Either.left(groupPropertyToUpdate);
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);
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);
575 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
576 SchemaDefinition def = property.getSchema();
578 log.debug("Schema doesn't exists for property of type {}", type);
579 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
581 PropertyDataDefinition propDef = def.getProperty();
582 if (propDef == null) {
583 log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
585 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
587 innerType = propDef.getType();
590 Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, allDataTypes);
592 String newValue = value;
593 if (isValid.isRight()) {
594 Boolean res = isValid.right().value();
596 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
599 Object object = isValid.left().value();
600 if (object != null) {
601 newValue = object.toString();
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));
612 return Either.left(newValue);
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);
619 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
620 SchemaDefinition def = property.getSchema();
622 log.debug("Schema doesn't exists for property of type {}", type);
623 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
625 PropertyDataDefinition propDef = def.getProperty();
626 if (propDef == null) {
627 log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
629 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
631 innerType = propDef.getType();
634 Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, allDataTypes);
636 String newValue = value;
637 if (isValid.isRight()) {
638 Boolean res = isValid.right().value();
640 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ILLEGAL_ARGUMENT));
643 Object object = isValid.left().value();
644 if (object != null) {
645 newValue = object.toString();
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));
656 return Either.left(newValue);
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);
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);
672 JsonElement jsonElement = validateResult.left;
673 String valueFromJsonElement = getValueFromJsonElement(jsonElement);
674 return Either.left(valueFromJsonElement);
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);
683 Object convertedValue = value;
684 if (false == isEmptyValue(value) && isValidate) {
685 PropertyValueConverter converter = type.getConverter();
686 convertedValue = converter.convert(value, innerType, dataTypes);
688 return Either.left(convertedValue);
691 public ImmutablePair<String, Boolean> validateAndUpdateRules(String propertyType, List<PropertyRule> rules, String innerType, Map<String, DataTypeDefinition> dataTypes, boolean isValidate) {
693 if (rules == null || rules.isEmpty() == true) {
694 return new ImmutablePair<String, Boolean>(null, true);
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);
706 String newValue = null;
707 Object object = updateResult.left().value();
708 if (object != null) {
709 newValue = object.toString();
711 rule.setValue(newValue);
715 return new ImmutablePair<String, Boolean>(null, true);
718 protected boolean isValidValue(ToscaPropertyType type, String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
719 if (isEmptyValue(value)) {
723 PropertyTypeValidator validator = type.getValidator();
725 boolean isValid = validator.isValid(value, innerType, dataTypes);
726 if (true == isValid) {
734 public boolean isEmptyValue(String value) {
741 public boolean isNullParam(String value) {
748 public void addRulesToNewPropertyValue(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) {
750 List<PropertyRule> rules = resourceInstanceProperty.getRules();
752 PropertyRule propertyRule = buildRuleFromPath(propertyValueData, resourceInstanceProperty, resourceInstanceId);
753 rules = new ArrayList<>();
754 rules.add(propertyRule);
756 rules = sortRules(rules);
759 propertyValueData.setRules(rules);
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
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);
772 PropertyRule propertyRule = new PropertyRule();
773 propertyRule.setRule(path);
774 propertyRule.setValue(propertyValueData.getValue());
778 private List<PropertyRule> sortRules(List<PropertyRule> rules) {
780 // TODO: sort the rules by size and binary representation.
781 // (x, y, .+) --> 110 6 priority 1
782 // (x, .+, z) --> 101 5 priority 2
787 protected String getValueFromJsonElement(JsonElement jsonElement) {
790 if (jsonElement == null || jsonElement.isJsonNull()) {
793 if (jsonElement.toString().isEmpty()) {
796 value = jsonElement.toString();