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=========================================================
19 * Modifications copyright (c) 2019 Nokia
20 * ================================================================================
22 package org.openecomp.sdc.be.components.impl;
24 import static org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR;
26 import com.google.gson.JsonElement;
27 import fj.data.Either;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Collections;
31 import java.util.List;
33 import java.util.function.Function;
34 import org.apache.commons.lang3.ArrayUtils;
35 import org.apache.commons.lang3.StringUtils;
36 import org.apache.commons.lang3.tuple.ImmutablePair;
37 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
38 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
39 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
40 import org.openecomp.sdc.be.components.validation.UserValidations;
41 import org.openecomp.sdc.be.config.BeEcompErrorManager;
42 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
43 import org.openecomp.sdc.be.dao.api.ActionStatus;
44 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao;
45 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
46 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao;
47 import org.openecomp.sdc.be.datamodel.utils.ArtifactUtils;
48 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
49 import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
50 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
51 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
52 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
53 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
54 import org.openecomp.sdc.be.impl.ComponentsUtils;
55 import org.openecomp.sdc.be.model.ArtifactDefinition;
56 import org.openecomp.sdc.be.model.Component;
57 import org.openecomp.sdc.be.model.ComponentInstInputsMap;
58 import org.openecomp.sdc.be.model.ComponentInstOutputsMap;
59 import org.openecomp.sdc.be.model.ComponentInstance;
60 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
61 import org.openecomp.sdc.be.model.ComponentParametersView;
62 import org.openecomp.sdc.be.model.DataTypeDefinition;
63 import org.openecomp.sdc.be.model.IComplexDefaultValue;
64 import org.openecomp.sdc.be.model.IPropertyInputCommon;
65 import org.openecomp.sdc.be.model.LifecycleStateEnum;
66 import org.openecomp.sdc.be.model.PolicyDefinition;
67 import org.openecomp.sdc.be.model.PropertyConstraint;
68 import org.openecomp.sdc.be.model.PropertyDefinition;
69 import org.openecomp.sdc.be.model.User;
70 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
71 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
72 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
73 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
74 import org.openecomp.sdc.be.model.operations.StorageException;
75 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
76 import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
77 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
78 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
79 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
80 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
81 import org.openecomp.sdc.be.model.operations.impl.AttributeOperation;
82 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
83 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
84 import org.openecomp.sdc.be.model.operations.impl.PolicyTypeOperation;
85 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
86 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
87 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
88 import org.openecomp.sdc.be.model.tosca.ToscaType;
89 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
90 import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter;
91 import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
92 import org.openecomp.sdc.be.user.Role;
93 import org.openecomp.sdc.be.user.UserBusinessLogic;
94 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
95 import org.openecomp.sdc.common.datastructure.Wrapper;
96 import org.openecomp.sdc.common.log.wrappers.Logger;
97 import org.openecomp.sdc.exception.ResponseFormat;
98 import org.springframework.beans.factory.annotation.Autowired;
100 public abstract class BaseBusinessLogic {
102 private static final String FAILED_TO_LOCK_COMPONENT_ERROR = "Failed to lock component {} error - {}";
103 private static final Logger log = Logger.getLogger(BaseBusinessLogic.class);
104 private static final String EMPTY_VALUE = null;
105 private static final String SCHEMA_DOESN_T_EXISTS_FOR_PROPERTY_OF_TYPE = "Schema doesn't exists for property of type {}";
106 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";
107 private static final String ADD_PROPERTY_VALUE = "Add property value";
108 private static final String THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID = "The value {} of property from type {} is invalid";
109 protected IGroupTypeOperation groupTypeOperation;
110 protected InterfaceOperation interfaceOperation;
111 protected IElementOperation elementDao;
112 protected ComponentsUtils componentsUtils;
113 protected UserBusinessLogic userAdmin;
114 protected IGraphLockOperation graphLockOperation;
115 protected JanusGraphDao janusGraphDao;
116 protected JanusGraphGenericDao janusGraphGenericDao;
117 protected PropertyOperation propertyOperation;
118 protected AttributeOperation attributeOperation;
119 protected ApplicationDataTypeCache applicationDataTypeCache;
120 protected ToscaOperationFacade toscaOperationFacade;
121 protected IGroupOperation groupOperation;
122 protected IGroupInstanceOperation groupInstanceOperation;
123 protected InterfaceLifecycleOperation interfaceLifecycleTypeOperation;
124 protected PolicyTypeOperation policyTypeOperation;
125 protected ArtifactsOperations artifactToscaOperation;
126 protected UserValidations userValidations;
127 DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
129 protected BaseBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation,
130 IGroupTypeOperation groupTypeOperation, InterfaceOperation interfaceOperation,
131 InterfaceLifecycleOperation interfaceLifecycleTypeOperation, ArtifactsOperations artifactToscaOperation) {
132 this.elementDao = elementDao;
133 this.groupOperation = groupOperation;
134 this.groupInstanceOperation = groupInstanceOperation;
135 this.groupTypeOperation = groupTypeOperation;
136 this.interfaceOperation = interfaceOperation;
137 this.interfaceLifecycleTypeOperation = interfaceLifecycleTypeOperation;
138 this.artifactToscaOperation = artifactToscaOperation;
142 static <T extends Enum<T>> boolean enumHasValueFilter(String name, Function<String, T> enumGetter, T... enumValues) {
143 T enumFound = enumGetter.apply(name);
144 return Arrays.asList(enumValues).contains(enumFound);
148 public void setUserAdmin(UserBusinessLogic userAdmin) {
149 this.userAdmin = userAdmin;
153 public void setUserValidations(UserValidations userValidations) {
154 this.userValidations = userValidations;
158 public void setComponentsUtils(ComponentsUtils componentsUtils) {
159 this.componentsUtils = componentsUtils;
163 public void setJanusGraphDao(JanusGraphDao janusGraphDao) {
164 this.janusGraphDao = janusGraphDao;
168 public void setApplicationDataTypeCache(ApplicationDataTypeCache applicationDataTypeCache) {
169 this.applicationDataTypeCache = applicationDataTypeCache;
173 public void setJanusGraphGenericDao(JanusGraphGenericDao janusGraphGenericDao) {
174 this.janusGraphGenericDao = janusGraphGenericDao;
178 public void setGraphLockOperation(IGraphLockOperation graphLockOperation) {
179 this.graphLockOperation = graphLockOperation;
183 public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
184 this.toscaOperationFacade = toscaOperationFacade;
188 void setPolicyTypeOperation(PolicyTypeOperation policyTypeOperation) {
189 this.policyTypeOperation = policyTypeOperation;
193 public void setPropertyOperation(PropertyOperation propertyOperation) {
194 this.propertyOperation = propertyOperation;
198 public void setAttributeOperation(AttributeOperation attributeOperation) {
199 this.attributeOperation = attributeOperation;
202 User validateUserNotEmpty(User user, String ecompErrorContext) {
203 return userValidations.validateUserNotEmpty(user, ecompErrorContext);
206 protected User validateUserExists(String userId) {
207 return userValidations.validateUserExists(userId);
210 public User validateUserExists(User user) {
211 return userValidations.validateUserExists(user);
214 ActionStatus validateUserExistsActionStatus(String userId) {
215 return userValidations.validateUserExistsActionStatus(userId);
218 protected void validateUserRole(User user, List<Role> roles) {
219 userValidations.validateUserRole(user, roles);
222 protected void lockComponent(Component component, String ecompErrorContext) {
223 lockComponent(component.getUniqueId(), component, ecompErrorContext);
226 protected boolean isVolumeGroup(List<String> artifactsInGroup, List<ArtifactDefinition> deploymentArtifacts) {
227 for (String artifactId : artifactsInGroup) {
228 ArtifactDefinition artifactDef = ArtifactUtils.findArtifactInList(deploymentArtifacts, artifactId);
229 if (artifactDef != null && artifactDef.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_VOL.getType())) {
236 protected void lockComponent(Component component, boolean shouldLock, String ecompErrorContext) {
238 lockComponent(component.getUniqueId(), component, ecompErrorContext);
242 protected void lockComponent(String componentId, Component component, String ecompErrorContext) {
243 ActionStatus lock = lockElement(componentId, component, ecompErrorContext);
244 if (lock != ActionStatus.OK) {
245 logAndThrowComponentException(lock, component.getUniqueId(), component.getName());
249 protected void lockComponent(String componentId, Component component, boolean needLock, String ecompErrorContext) {
251 lockComponent(componentId, component, ecompErrorContext);
255 private ResponseFormat logAndThrowComponentException(ActionStatus status, String componentId, String name) {
256 log.debug(FAILED_TO_LOCK_COMPONENT_ERROR, componentId, status);
257 throw new ByActionStatusComponentException(status, name);
260 private ActionStatus lockElement(String componentId, Component component, String ecompErrorContext) {
261 ComponentTypeEnum componentType = component.getComponentType();
262 NodeTypeEnum nodeType = componentType.getNodeType();
263 StorageOperationStatus lockResourceStatus = graphLockOperation.lockComponent(componentId, nodeType);
264 if (lockResourceStatus == StorageOperationStatus.OK) {
265 return ActionStatus.OK;
267 BeEcompErrorManager.getInstance().logBeFailedLockObjectError(ecompErrorContext, nodeType.getName(), componentId);
268 return componentsUtils.convertFromStorageResponse(lockResourceStatus, componentType);
272 protected void unlockComponent(boolean failed, Component component, boolean inTransaction) {
273 if (component != null) {
274 ComponentTypeEnum componentType = component.getComponentType();
275 NodeTypeEnum nodeType = componentType.getNodeType();
276 if (!inTransaction) {
278 janusGraphDao.rollback();
280 janusGraphDao.commit();
284 graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
286 log.debug("component is NULL");
290 protected void unlockComponent(boolean failed, Component component) {
291 unlockComponent(failed, component, false);
294 void unlockComponentById(boolean failed, String componentId) {
295 Either<Component, StorageOperationStatus> component = toscaOperationFacade.getToscaElement(componentId);
296 if (component.isLeft()) {
297 unlockComponent(failed, component.left().value(), false);
301 <T> Boolean validateJsonBody(T bodyObject, Class<T> clazz) {
302 if (bodyObject == null) {
303 log.debug("Invalid JSON received for object of type {}", clazz.getSimpleName());
304 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
310 ComponentTypeEnum validateComponentType(String componentType) {
311 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
312 if (componentTypeEnum == null) {
313 log.debug("Invalid component type {}", componentType);
314 throw new ByActionStatusComponentException(ActionStatus.UNSUPPORTED_ERROR, componentType);
316 return componentTypeEnum;
320 Component validateComponentExists(String componentId, ComponentTypeEnum componentType, ComponentParametersView filter) {
321 Either<Component, StorageOperationStatus> toscaElement = toscaOperationFacade
322 .getToscaElement(componentId, filter == null ? new ComponentParametersView() : filter);
323 if (toscaElement.isRight()) {
324 handleGetComponentError(componentId, componentType, toscaElement.right().value());
326 return validateComponentType(toscaElement.left().value(), componentType);
329 private Component validateComponentType(Component cmpt, ComponentTypeEnum componentType) {
330 if (componentType != cmpt.getComponentType()) {
331 log.debug("component {} is not of requested type {}", cmpt.getUniqueId(), componentType);
332 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, componentType));
337 <T extends PropertyDataDefinition> String updateInputPropertyObjectValue(T property) {
338 String propertyType = property.getType();
339 String innerType = getInnerType(property);
340 // Specific Update Logic
341 Either<Object, Boolean> isValid = propertyOperation
342 .validateAndUpdatePropertyValue(propertyType, property.getValue(), true, innerType,
343 componentsUtils.getAllDataTypes(applicationDataTypeCache, property.getModel()));
344 String newValue = property.getValue();
345 if (isValid.isRight()) {
346 Boolean res = isValid.right().value();
347 if (Boolean.FALSE.equals(res)) {
348 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(
349 DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT)));
352 Object object = isValid.left().value();
353 if (object != null) {
354 newValue = object.toString();
360 <T extends PropertyDataDefinition> String getInnerType(T property) {
361 ToscaPropertyType type = ToscaPropertyType.isValidType(property.getType());
362 log.debug("#getInnerType - The type of the property {} is {}", property.getUniqueId(), property.getType());
363 String innerType = null;
364 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
365 if (property.getSchema() == null) {
366 log.debug(SCHEMA_DOESN_T_EXISTS_FOR_PROPERTY_OF_TYPE, type);
367 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE));
369 PropertyDataDefinition innerProperty = property.getSchema().getProperty();
370 if (innerProperty == null) {
371 log.debug(PROPERTY_IN_SCHEMA_DEFINITION_INSIDE_PROPERTY_OF_TYPE_DOESN_T_EXIST, type);
372 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE));
374 innerType = innerProperty.getType();
379 public void validateCanWorkOnComponent(Component component, String userId) {
380 ActionStatus actionStatus = ActionStatus.RESTRICTED_OPERATION;
381 // verify resource is not archived
382 if (Boolean.TRUE.equals(component.isArchived())) {
383 actionStatus = ActionStatus.COMPONENT_IS_ARCHIVED;
384 throw new ByActionStatusComponentException(actionStatus, component.getName());
386 if (component.getLifecycleState() != LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) {
387 log.debug("Component {} is not checked-out", component.getName());
388 throw new ByActionStatusComponentException(actionStatus);
390 // verify userId is not null
391 if (userId == null) {
392 log.debug("Current user userId is null");
393 throw new ByActionStatusComponentException(actionStatus);
395 // verify component last update user is the current user
396 String lastUpdaterUserId = component.getLastUpdaterUserId();
397 if (!userId.equals(lastUpdaterUserId)) {
398 log.debug("Current user is not last updater, last updater userId: {}, current user userId: {}", lastUpdaterUserId, userId);
399 throw new ByActionStatusComponentException(actionStatus);
401 // verify resource is not deleted
402 if (Boolean.TRUE.equals(component.getIsDeleted())) {
403 log.debug("Component {} is marked as deleted", component.getUniqueId());
404 throw new ByActionStatusComponentException(actionStatus);
408 ComponentTypeEnum getComponentTypeByParentComponentType(ComponentTypeEnum parentComponentType) {
409 switch (parentComponentType) {
412 return ComponentTypeEnum.RESOURCE;
414 return ComponentTypeEnum.SERVICE;
421 Either<Boolean, ResponseFormat> validatePropertyDefaultValue(IComplexDefaultValue property, Map<String, DataTypeDefinition> dataTypes) {
423 String innerType = null;
424 if (!propertyOperation.isPropertyTypeValid(property, null)) {
425 log.info("Invalid type for property '{}' type '{}'", property.getName(), property.getType());
426 ResponseFormat responseFormat = componentsUtils
427 .getResponseFormat(ActionStatus.INVALID_PROPERTY_TYPE, property.getType(), property.getName());
428 return Either.right(responseFormat);
430 type = property.getType();
431 if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
432 ImmutablePair<String, Boolean> propertyInnerTypeValid = propertyOperation.isPropertyInnerTypeValid(property, dataTypes);
433 innerType = propertyInnerTypeValid.getLeft();
434 if (Boolean.FALSE.equals(propertyInnerTypeValid.getRight())) {
435 log.info("Invalid inner type for property '{}' type '{}', dataTypeCount '{}'", property.getName(), property.getType(),
437 ResponseFormat responseFormat = componentsUtils
438 .getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE, innerType, property.getName());
439 return Either.right(responseFormat);
442 if (!propertyOperation.isPropertyDefaultValueValid(property, dataTypes)) {
443 log.info("Invalid default value for property '{}' type '{}'", property.getName(), property.getType());
444 ResponseFormat responseFormat;
445 if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
446 responseFormat = componentsUtils
447 .getResponseFormat(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE, property.getName(), type, innerType, property.getDefaultValue());
449 responseFormat = componentsUtils
450 .getResponseFormat(ActionStatus.INVALID_DEFAULT_VALUE, property.getName(), type, property.getDefaultValue());
452 return Either.right(responseFormat);
454 return Either.left(true);
457 void validateComponentTypeEnum(ComponentTypeEnum componentTypeEnum, String errorContext, Wrapper<ResponseFormat> errorWrapper) {
458 if (componentTypeEnum == null) {
459 BeEcompErrorManager.getInstance().logInvalidInputError(errorContext, "invalid component type", ErrorSeverity.INFO);
460 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
464 protected void validateCanWorkOnComponent(String componentId, ComponentTypeEnum componentTypeEnum, String userId,
465 Wrapper<ResponseFormat> errorWrapper) {
466 if (!ComponentValidationUtils.canWorkOnComponent(componentId, toscaOperationFacade, userId)) {
467 log.info("Restricted operation for user {} on {} {}", userId, componentTypeEnum.getValue(), componentId);
468 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
472 void validateComponentLock(String componentId, ComponentTypeEnum componentTypeEnum, Wrapper<ResponseFormat> errorWrapper) {
473 StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType());
474 if (lockStatus != StorageOperationStatus.OK) {
475 log.debug("Failed to lock {} {}", componentTypeEnum.getValue(), componentId);
476 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
480 protected ToscaPropertyType getType(String propertyType) {
481 return ToscaPropertyType.isValidType(propertyType);
484 void commitOrRollback(Either<?, ResponseFormat> result) {
485 if (result == null || result.isRight()) {
486 log.warn("operation failed. do rollback");
487 janusGraphDao.rollback();
489 log.debug("operation success. do commit");
490 janusGraphDao.commit();
494 protected Either<Boolean, ResponseFormat> lockComponentByName(String name, Component component, String ecompErrorContext) {
495 ComponentTypeEnum componentType = component.getComponentType();
496 NodeTypeEnum nodeType = componentType.getNodeType();
497 StorageOperationStatus lockResourceStatus = graphLockOperation.lockComponentByName(name, nodeType);
498 if (lockResourceStatus == StorageOperationStatus.OK) {
499 return Either.left(true);
501 BeEcompErrorManager.getInstance().logBeFailedLockObjectError(ecompErrorContext, nodeType.getName(), name);
502 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(lockResourceStatus, componentType);
503 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, component.getName());
504 log.debug(FAILED_TO_LOCK_COMPONENT_ERROR, name, actionStatus);
505 return Either.right(responseFormat);
509 protected Component validateComponentExistsByFilter(String componentId, ComponentTypeEnum componentType,
510 ComponentParametersView componentParametersView) {
511 return toscaOperationFacade.getToscaElement(componentId, componentParametersView).left()
512 .on(err -> handleGetComponentError(componentId, componentType, err));
515 private Component handleGetComponentError(String componentId, ComponentTypeEnum componentType, StorageOperationStatus getComponentError) {
516 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentError, componentType);
517 log.debug("error fetching component with id {}. error status: {}", componentId, getComponentError);
518 throw new ByActionStatusComponentException(actionStatus, componentId);
521 String validatePropValueBeforeCreate(IPropertyInputCommon property, String value, boolean isValidate,
522 Map<String, DataTypeDefinition> allDataTypes) {
523 String propertyType = property.getType();
524 String updatedInnerType = updateInnerType(property);
525 Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value, isValidate, updatedInnerType, allDataTypes);
526 String newValue = value;
527 if (isValid.isRight()) {
528 Boolean res = isValid.right().value();
529 if (Boolean.FALSE.equals(res)) {
530 throw new StorageException(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT));
533 Object object = isValid.left().value();
534 if (object != null) {
535 newValue = object.toString();
538 ImmutablePair<String, Boolean> pair = validateAndUpdateRules(propertyType, property.getRules(), updatedInnerType, allDataTypes, isValidate);
539 log.trace("After validateAndUpdateRules. pair = {}", pair);
540 if (Boolean.FALSE.equals(pair.getRight())) {
541 BeEcompErrorManager.getInstance().logBeInvalidValueError(ADD_PROPERTY_VALUE, pair.getLeft(), property.getName(), propertyType);
542 throw new StorageException(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT));
547 private String updateInnerType(IPropertyInputCommon property) {
548 ToscaPropertyType type = ToscaPropertyType.isValidType(property.getType());
549 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
550 SchemaDefinition def = property.getSchema();
552 log.debug(SCHEMA_DOESN_T_EXISTS_FOR_PROPERTY_OF_TYPE, type);
553 failOnIllegalArgument();
555 PropertyDataDefinition propDef = def.getProperty();
556 if (propDef == null) {
557 log.debug(PROPERTY_IN_SCHEMA_DEFINITION_INSIDE_PROPERTY_OF_TYPE_DOESN_T_EXIST, type);
558 failOnIllegalArgument();
560 return propDef.getType();
565 private void failOnIllegalArgument() {
566 throw new ByActionStatusComponentException(componentsUtils
567 .convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT)));
570 public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, boolean isValidate, String innerType,
571 Map<String, DataTypeDefinition> dataTypes) {
572 log.trace("Going to validate property value and its type. type = {}, value = {}", propertyType, value);
573 ToscaPropertyType type = getType(propertyType);
576 DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
577 ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter
578 .validateAndUpdate(value, dataTypeDefinition, dataTypes);
579 if (Boolean.FALSE.equals(validateResult.right)) {
580 log.debug(THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID, value, propertyType);
581 return Either.right(false);
583 JsonElement jsonElement = validateResult.left;
584 String valueFromJsonElement = getValueFromJsonElement(jsonElement);
585 return Either.left(valueFromJsonElement);
587 log.trace("before validating property type {}", propertyType);
588 boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
589 if (!isValidProperty) {
590 log.debug(THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID, value, type);
591 return Either.right(false);
594 Object convertedValue = value;
595 if (!isEmptyValue(value) && isValidate) {
596 PropertyValueConverter converter = type.getConverter();
597 convertedValue = converter.convert(value, innerType, dataTypes);
599 return Either.left(convertedValue);
602 private ImmutablePair<String, Boolean> validateAndUpdateRules(String propertyType, List<PropertyRule> rules, String innerType,
603 Map<String, DataTypeDefinition> dataTypes, boolean isValidate) {
604 if (rules == null || rules.isEmpty()) {
605 return ImmutablePair.of(null, true);
607 for (PropertyRule rule : rules) {
608 String value = rule.getValue();
609 Either<Object, Boolean> updateResult = validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, dataTypes);
610 if (updateResult.isRight()) {
611 Boolean status = updateResult.right().value();
612 if (Boolean.FALSE.equals(status)) {
613 return ImmutablePair.of(value, status);
616 String newValue = null;
617 Object object = updateResult.left().value();
618 if (object != null) {
619 newValue = object.toString();
621 rule.setValue(newValue);
624 return ImmutablePair.of(null, true);
627 protected boolean isValidValue(ToscaPropertyType type, String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
628 if (isEmptyValue(value)) {
631 PropertyTypeValidator validator = type.getValidator();
632 return validator.isValid(value, innerType, dataTypes);
635 public boolean isEmptyValue(String value) {
636 return value == null;
639 protected String getValueFromJsonElement(JsonElement jsonElement) {
640 if (jsonElement == null || jsonElement.isJsonNull()) {
643 if (jsonElement.toString().isEmpty()) {
646 return jsonElement.toString();
649 protected void rollbackWithException(ActionStatus actionStatus, String... params) {
650 janusGraphDao.rollback();
651 throw new ByActionStatusComponentException(actionStatus, params);
654 public <T extends ToscaDataDefinition> Either<List<T>, ResponseFormat> declareProperties(final String userId, final String componentId,
655 final ComponentTypeEnum componentTypeEnum,
656 final ComponentInstInputsMap componentInstInputsMap) {
657 return Either.left(new ArrayList<>());
660 public <T extends ToscaDataDefinition> Either<List<T>, ResponseFormat> declareAttributes(final String userId, final String componentId,
661 final ComponentTypeEnum componentTypeEnum,
662 final ComponentInstOutputsMap componentInstOutputsMap) {
663 return Either.left(new ArrayList<>());
666 public <T extends PropertyDataDefinition> List<PropertyConstraint> setInputConstraint(T inputDefinition) {
667 if (StringUtils.isNotBlank(inputDefinition.getParentPropertyType()) && StringUtils.isNotBlank(inputDefinition.getSubPropertyInputPath())) {
668 return setConstraint(inputDefinition);
670 return Collections.emptyList();
673 private <T extends PropertyDataDefinition> List<PropertyConstraint> setConstraint(T inputDefinition) {
674 List<PropertyConstraint> constraints = new ArrayList<>();
675 String[] inputPathArr = inputDefinition.getSubPropertyInputPath().split("#");
676 if (inputPathArr.length > 1) {
677 inputPathArr = ArrayUtils.remove(inputPathArr, 0);
679 final Map<String, DataTypeDefinition> dataTypeDefinitionMap =
680 componentsUtils.getAllDataTypes(applicationDataTypeCache, inputDefinition.getModel());
681 String propertyType = inputDefinition.getParentPropertyType();
682 for (String anInputPathArr : inputPathArr) {
683 if (ToscaType.isPrimitiveType(propertyType)) {
684 constraints.addAll(dataTypeDefinitionMap.get(propertyType).getConstraints());
685 } else if (!ToscaType.isCollectionType(propertyType)) {
686 propertyType = setConstraintForComplexType(dataTypeDefinitionMap, propertyType, anInputPathArr, constraints);
692 private String setConstraintForComplexType(Map<String, DataTypeDefinition> dataTypeDefinitionMap, String propertyType, String anInputPathArr,
693 List<PropertyConstraint> constraints) {
695 List<PropertyDefinition> propertyDefinitions = dataTypeDefinitionMap.get(propertyType).getProperties();
696 for (PropertyDefinition propertyDefinition : propertyDefinitions) {
697 if (propertyDefinition.getName().equals(anInputPathArr)) {
698 if (ToscaType.isPrimitiveType(propertyDefinition.getType())) {
699 constraints.addAll(propertyDefinition.safeGetConstraints());
701 type = propertyDefinition.getType();
709 protected void unlockRollbackWithException(Component component, RuntimeException e) {
710 janusGraphDao.rollback();
711 graphLockOperation.unlockComponent(component.getUniqueId(), component.getComponentType().getNodeType());
715 protected void unlockWithCommit(Component component) {
716 ComponentTypeEnum componentType = component.getComponentType();
717 NodeTypeEnum nodeType = componentType.getNodeType();
718 janusGraphDao.commit();
719 graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
722 protected ComponentInstance componentInstanceException(StorageOperationStatus storageOperationStatus) {
723 throw new StorageException(storageOperationStatus);
726 protected Component componentException(StorageOperationStatus storageOperationStatus) {
727 throw new StorageException(storageOperationStatus);
730 protected PolicyDefinition componentExceptionPolicyDefinition(ResponseFormat responseFormat) {
731 throw new ByResponseFormatComponentException(responseFormat);
734 protected List<ComponentInstanceProperty> componentInstancePropertyListException(StorageOperationStatus storageOperationStatus) {
735 throw new StorageException(storageOperationStatus);
738 protected Component getComponent(final String componentId) throws BusinessLogicException {
739 final Either<Component, StorageOperationStatus> result = toscaOperationFacade.getToscaElement(componentId);
740 if (result.isRight()) {
741 final StorageOperationStatus errorStatus = result.right().value();
742 log.error(BUSINESS_PROCESS_ERROR, this.getClass().getName(), "Failed to fetch component information by component id, error {}",
744 throw new BusinessLogicException(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
746 return result.left().value();
749 public String getComponentModelByComponentId(final String componentId) throws BusinessLogicException {
750 return getComponent(componentId).getModel();