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 * ================================================================================
23 package org.openecomp.sdc.be.components.impl;
25 import com.google.gson.JsonElement;
26 import fj.data.Either;
27 import org.apache.commons.lang3.ArrayUtils;
28 import org.apache.commons.lang3.StringUtils;
29 import org.apache.commons.lang3.tuple.ImmutablePair;
30 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
31 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
32 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
33 import org.openecomp.sdc.be.components.validation.UserValidations;
34 import org.openecomp.sdc.be.config.BeEcompErrorManager;
35 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
36 import org.openecomp.sdc.be.dao.api.ActionStatus;
37 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao;
38 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
39 import org.openecomp.sdc.be.dao.jsongraph.JanusGraphDao;
40 import org.openecomp.sdc.be.datamodel.utils.ArtifactUtils;
41 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
42 import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
43 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
44 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
45 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
46 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
47 import org.openecomp.sdc.be.impl.ComponentsUtils;
48 import org.openecomp.sdc.be.model.ArtifactDefinition;
49 import org.openecomp.sdc.be.model.Component;
50 import org.openecomp.sdc.be.model.ComponentInstInputsMap;
51 import org.openecomp.sdc.be.model.ComponentInstance;
52 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
53 import org.openecomp.sdc.be.model.ComponentParametersView;
54 import org.openecomp.sdc.be.model.DataTypeDefinition;
55 import org.openecomp.sdc.be.model.IComplexDefaultValue;
56 import org.openecomp.sdc.be.model.IPropertyInputCommon;
57 import org.openecomp.sdc.be.model.LifecycleStateEnum;
58 import org.openecomp.sdc.be.model.PolicyDefinition;
59 import org.openecomp.sdc.be.model.PropertyConstraint;
60 import org.openecomp.sdc.be.model.PropertyDefinition;
61 import org.openecomp.sdc.be.model.User;
62 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
63 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
64 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
65 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
66 import org.openecomp.sdc.be.model.operations.StorageException;
67 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
68 import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
69 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
70 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
71 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
72 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
73 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
74 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
75 import org.openecomp.sdc.be.model.operations.impl.PolicyTypeOperation;
76 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
77 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
78 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
79 import org.openecomp.sdc.be.model.tosca.ToscaType;
80 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
81 import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter;
82 import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
83 import org.openecomp.sdc.be.user.Role;
84 import org.openecomp.sdc.be.user.UserBusinessLogic;
85 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
86 import org.openecomp.sdc.common.datastructure.Wrapper;
87 import org.openecomp.sdc.common.log.wrappers.Logger;
88 import org.openecomp.sdc.exception.ResponseFormat;
89 import org.springframework.beans.factory.annotation.Autowired;
91 import java.util.ArrayList;
92 import java.util.Arrays;
93 import java.util.Collections;
94 import java.util.List;
96 import java.util.function.Function;
98 public abstract class BaseBusinessLogic {
100 private static final String FAILED_TO_LOCK_COMPONENT_ERROR = "Failed to lock component {} error - {}";
102 private static final Logger log = Logger.getLogger(BaseBusinessLogic.class.getName());
103 private static final String EMPTY_VALUE = null;
104 private static final String SCHEMA_DOESN_T_EXISTS_FOR_PROPERTY_OF_TYPE = "Schema doesn't exists for property of type {}";
105 private static final String PROPERTY_IN_SCHEMA_DEFINITION_INSIDE_PROPERTY_OF_TYPE_DOESN_T_EXIST = "Property in Schema Definition inside property of type {} doesn't exist";
106 private static final String ADD_PROPERTY_VALUE = "Add property value";
107 private static final String THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID = "The value {} of property from type {} is invalid";
108 protected IGroupTypeOperation groupTypeOperation;
109 protected InterfaceOperation interfaceOperation;
110 protected IElementOperation elementDao;
111 protected ComponentsUtils componentsUtils;
112 protected UserBusinessLogic userAdmin;
113 protected IGraphLockOperation graphLockOperation;
114 protected JanusGraphDao janusGraphDao;
115 protected JanusGraphGenericDao janusGraphGenericDao;
116 protected PropertyOperation propertyOperation;
117 protected ApplicationDataTypeCache applicationDataTypeCache;
118 protected ToscaOperationFacade toscaOperationFacade;
119 protected ApplicationDataTypeCache dataTypeCache;
120 protected IGroupOperation groupOperation;
121 protected IGroupInstanceOperation groupInstanceOperation;
122 protected InterfaceLifecycleOperation interfaceLifecycleTypeOperation;
123 protected PolicyTypeOperation policyTypeOperation;
124 protected ArtifactsOperations artifactToscaOperation;
125 protected UserValidations userValidations;
127 DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
129 public BaseBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation,
130 IGroupInstanceOperation groupInstanceOperation, IGroupTypeOperation groupTypeOperation, InterfaceOperation interfaceOperation,
131 InterfaceLifecycleOperation interfaceLifecycleTypeOperation, ArtifactsOperations artifactToscaOperation) {
132 this.elementDao = elementDao;
133 this.groupOperation = groupOperation;
134 this.groupInstanceOperation = groupInstanceOperation;
135 this.groupTypeOperation = groupTypeOperation;
136 this.interfaceOperation = interfaceOperation;
137 this.interfaceLifecycleTypeOperation = interfaceLifecycleTypeOperation;
138 this.artifactToscaOperation = artifactToscaOperation;
142 public void setUserAdmin(UserBusinessLogic userAdmin) {
143 this.userAdmin = userAdmin;
147 public void setUserValidations(UserValidations userValidations) {
148 this.userValidations = userValidations;
152 public void setComponentsUtils(ComponentsUtils componentsUtils) {
153 this.componentsUtils = componentsUtils;
157 public void setJanusGraphDao(JanusGraphDao janusGraphDao) {
158 this.janusGraphDao = janusGraphDao;
162 public void setApplicationDataTypeCache(ApplicationDataTypeCache applicationDataTypeCache) {
163 this.applicationDataTypeCache = applicationDataTypeCache;
167 public void setJanusGraphGenericDao(JanusGraphGenericDao janusGraphGenericDao) {
168 this.janusGraphGenericDao = janusGraphGenericDao;
172 public void setGraphLockOperation(IGraphLockOperation graphLockOperation) {
173 this.graphLockOperation = graphLockOperation;
177 public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
178 this.toscaOperationFacade = toscaOperationFacade;
182 void setPolicyTypeOperation(PolicyTypeOperation policyTypeOperation) {
183 this.policyTypeOperation = policyTypeOperation;
187 public void setDataTypeCache(ApplicationDataTypeCache dataTypeCache) {
188 this.dataTypeCache = dataTypeCache;
192 public void setPropertyOperation(PropertyOperation propertyOperation) {
193 this.propertyOperation = propertyOperation;
196 User validateUserNotEmpty(User user, String ecompErrorContext) {
197 return userValidations.validateUserNotEmpty(user, ecompErrorContext);
200 protected User validateUserExists(String userId) {
201 return userValidations.validateUserExists(userId);
204 public User validateUserExists(User user) {
205 return userValidations.validateUserExists(user);
208 ActionStatus validateUserExistsActionStatus(String userId) {
209 return userValidations.validateUserExistsActionStatus(userId);
212 protected void validateUserRole(User user, List<Role> roles) {
213 userValidations.validateUserRole(user, roles);
216 protected void lockComponent(Component component, String ecompErrorContext) {
217 lockComponent(component.getUniqueId(), component, ecompErrorContext);
220 protected boolean isVolumeGroup(List<String> artifactsInGroup,List <ArtifactDefinition> deploymentArtifacts) {
221 for (String artifactId : artifactsInGroup) {
222 ArtifactDefinition artifactDef = ArtifactUtils.findArtifactInList(deploymentArtifacts, artifactId);
223 if (artifactDef != null
224 && artifactDef.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_VOL.getType())) {
231 protected void lockComponent(Component component, boolean shouldLock, String ecompErrorContext) {
233 lockComponent(component.getUniqueId(), component, ecompErrorContext);
237 protected void lockComponent(String componentId, Component component, String ecompErrorContext) {
238 ActionStatus lock = lockElement(componentId, component, ecompErrorContext);
239 if ( lock!= ActionStatus.OK ) {
240 logAndThrowComponentException(lock, component.getUniqueId(), component.getName());
244 protected void lockComponent(String componentId, Component component, boolean needLock, String ecompErrorContext) {
246 lockComponent(componentId, component, ecompErrorContext);
250 private ResponseFormat logAndThrowComponentException(ActionStatus status, String componentId, String name){
251 log.debug(FAILED_TO_LOCK_COMPONENT_ERROR, componentId, status);
252 throw new ByActionStatusComponentException(status, name);
255 private ActionStatus lockElement(String componentId, Component component, String ecompErrorContext) {
256 ComponentTypeEnum componentType = component.getComponentType();
257 NodeTypeEnum nodeType = componentType.getNodeType();
258 StorageOperationStatus lockResourceStatus = graphLockOperation.lockComponent(componentId, nodeType);
260 if (lockResourceStatus == StorageOperationStatus.OK) {
261 return ActionStatus.OK;
263 BeEcompErrorManager.getInstance().logBeFailedLockObjectError(ecompErrorContext, nodeType.getName(), componentId);
264 return componentsUtils.convertFromStorageResponse(lockResourceStatus, componentType);
268 protected void unlockComponent(boolean failed, Component component, boolean inTransaction) {
269 if (component != null) {
270 ComponentTypeEnum componentType = component.getComponentType();
271 NodeTypeEnum nodeType = componentType.getNodeType();
272 if (!inTransaction) {
274 janusGraphDao.rollback();
276 janusGraphDao.commit();
280 graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
282 else log.debug("component is NULL");
285 protected void unlockComponent(boolean failed, Component component) {
286 unlockComponent(failed, component, false);
288 void unlockComponentById(boolean failed, String componentId) {
289 Either<Component, StorageOperationStatus> component = toscaOperationFacade.getToscaElement(componentId);
290 if(component.isLeft()) {
291 unlockComponent(failed, component.left().value(), false);
295 <T> Boolean validateJsonBody(T bodyObject, Class<T> clazz) {
296 if (bodyObject == null) {
297 log.debug("Invalid JSON received for object of type {}", clazz.getSimpleName());
298 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
305 ComponentTypeEnum validateComponentType(String componentType) {
306 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
307 if (componentTypeEnum == null) {
308 log.debug("Invalid component type {}", componentType);
309 throw new ByActionStatusComponentException(ActionStatus.UNSUPPORTED_ERROR, componentType);
311 return componentTypeEnum;
315 Component validateComponentExists(String componentId, ComponentTypeEnum componentType, ComponentParametersView filter) {
317 Either<Component, StorageOperationStatus> toscaElement = toscaOperationFacade.getToscaElement(componentId, filter == null ? new ComponentParametersView() : filter);
318 if(toscaElement.isRight()){
319 handleGetComponentError(componentId, componentType, toscaElement.right().value());
321 return validateComponentType(toscaElement.left().value(), componentType);
324 private Component validateComponentType(Component cmpt, ComponentTypeEnum componentType) {
325 if (componentType != cmpt.getComponentType()) {
326 log.debug("component {} is not of requested type {}", cmpt.getUniqueId(), componentType);
327 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, componentType));
332 <T extends PropertyDataDefinition> String updateInputPropertyObjectValue(T property) {
333 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypesEither = dataTypeCache.getAll();
334 if (allDataTypesEither.isRight()) {
335 JanusGraphOperationStatus status = allDataTypesEither.right().value();
336 BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR);
337 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status)));
339 Map<String, DataTypeDefinition> allDataTypes = allDataTypesEither.left().value();
340 String propertyType = property.getType();
341 String innerType = getInnerType(property);
342 // Specific Update Logic
343 Either<Object, Boolean> isValid =
344 propertyOperation.validateAndUpdatePropertyValue(propertyType, (String) property.getValue(), true,
345 innerType, allDataTypes);
346 String newValue = property.getValue();
347 if (isValid.isRight()) {
348 Boolean res = isValid.right().value();
349 if (Boolean.FALSE.equals(res)) {
350 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT)));
353 Object object = isValid.left().value();
354 if (object != null) {
355 newValue = object.toString();
361 <T extends PropertyDataDefinition> String getInnerType(T property){
362 ToscaPropertyType type = ToscaPropertyType.isValidType(property.getType());
363 log.debug("#getInnerType - The type of the property {} is {}", property.getUniqueId(), property.getType());
364 String innerType = null;
365 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
366 if (property.getSchema() == null) {
367 log.debug(SCHEMA_DOESN_T_EXISTS_FOR_PROPERTY_OF_TYPE, type);
368 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE));
370 PropertyDataDefinition innerProperty = property.getSchema().getProperty();
371 if (innerProperty == null) {
372 log.debug(PROPERTY_IN_SCHEMA_DEFINITION_INSIDE_PROPERTY_OF_TYPE_DOESN_T_EXIST, type);
373 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE));
375 innerType = innerProperty.getType();
380 public void validateCanWorkOnComponent(Component component, String userId) {
381 ActionStatus actionStatus = ActionStatus.RESTRICTED_OPERATION;
382 // verify resource is not archived
383 if (component.isArchived() == true){
384 actionStatus = ActionStatus.COMPONENT_IS_ARCHIVED;
385 throw new ByActionStatusComponentException(actionStatus, component.getName());
388 if (component.getLifecycleState() != LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) {
389 log.debug("Component {} is not checked-out", component.getName());
390 throw new ByActionStatusComponentException(actionStatus);
393 // verify userId is not null
394 if (userId == null) {
395 log.debug("Current user userId is null");
396 throw new ByActionStatusComponentException(actionStatus);
399 // verify component last update user is the current user
400 String lastUpdaterUserId = component.getLastUpdaterUserId();
401 if (!userId.equals(lastUpdaterUserId)) {
402 log.debug("Current user is not last updater, last updater userId: {}, current user userId: {}", lastUpdaterUserId, userId);
403 throw new ByActionStatusComponentException(actionStatus);
406 // verify resource is not deleted
407 if (Boolean.TRUE.equals(component.getIsDeleted())) {
408 log.debug("Component {} is marked as deleted", component.getUniqueId());
409 throw new ByActionStatusComponentException(actionStatus);
415 ComponentTypeEnum getComponentTypeByParentComponentType(ComponentTypeEnum parentComponentType) {
416 switch (parentComponentType) {
419 return ComponentTypeEnum.RESOURCE;
421 return ComponentTypeEnum.SERVICE;
430 protected Map<String, DataTypeDefinition> getAllDataTypes(ApplicationDataTypeCache applicationDataTypeCache) {
431 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes = applicationDataTypeCache.getAll();
432 if (allDataTypes.isRight()) {
433 JanusGraphOperationStatus operationStatus = allDataTypes.right().value();
434 if (operationStatus == JanusGraphOperationStatus.NOT_FOUND) {
435 BeEcompErrorManager.getInstance().logInternalDataError("FetchDataTypes", "Data types are not loaded", ErrorSeverity.ERROR);
436 throw new ByActionStatusComponentException(ActionStatus.DATA_TYPE_CANNOT_BE_EMPTY);
438 BeEcompErrorManager.getInstance().logInternalFlowError("FetchDataTypes", "Failed to fetch data types", ErrorSeverity.ERROR);
439 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
442 return allDataTypes.left().value();
445 Either<Boolean, ResponseFormat> validatePropertyDefaultValue(IComplexDefaultValue property, Map<String, DataTypeDefinition> dataTypes) {
447 String innerType = null;
448 if (!propertyOperation.isPropertyTypeValid(property)) {
449 log.info("Invalid type for property '{}' type '{}'", property.getName(), property.getType());
450 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_TYPE, property.getType(), property.getName());
451 return Either.right(responseFormat);
453 type = property.getType();
454 if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
455 ImmutablePair<String, Boolean> propertyInnerTypeValid = propertyOperation.isPropertyInnerTypeValid(property, dataTypes);
456 innerType = propertyInnerTypeValid.getLeft();
457 if (!propertyInnerTypeValid.getRight()) {
458 log.info("Invalid inner type for property '{}' type '{}', dataTypeCount '{}'", property.getName(), property.getType(), dataTypes.size());
459 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE, innerType, property.getName());
460 return Either.right(responseFormat);
463 if (!propertyOperation.isPropertyDefaultValueValid(property, dataTypes)) {
464 log.info("Invalid default value for property '{}' type '{}'", property.getName(), property.getType());
465 ResponseFormat responseFormat;
466 if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
467 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE, property.getName(), type, innerType,
468 property.getDefaultValue());
470 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEFAULT_VALUE, property.getName(), type,
471 property.getDefaultValue());
473 return Either.right(responseFormat);
476 return Either.left(true);
480 void handleDefaultValue(IComplexDefaultValue newAttributeDef, Map<String, DataTypeDefinition> dataTypes) {
482 ToscaPropertyType type = ToscaPropertyType.isValidType(newAttributeDef.getType());
483 PropertyValueConverter converter = type.getConverter();
485 String innerType = null;
487 SchemaDefinition schema = newAttributeDef.getSchema();
488 if (schema != null) {
489 PropertyDataDefinition prop = schema.getProperty();
490 if (schema.getProperty() != null) {
491 innerType = prop.getType();
494 String convertedValue;
495 if (newAttributeDef.getDefaultValue() != null) {
496 convertedValue = converter.convert(newAttributeDef.getDefaultValue(), innerType, dataTypes);
497 newAttributeDef.setDefaultValue(convertedValue);
501 void validateComponentTypeEnum(ComponentTypeEnum componentTypeEnum, String errorContext, Wrapper<ResponseFormat> errorWrapper) {
502 if (componentTypeEnum == null) {
503 BeEcompErrorManager.getInstance().logInvalidInputError(errorContext, "invalid component type", ErrorSeverity.INFO);
504 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
509 protected void validateCanWorkOnComponent(String componentId, ComponentTypeEnum componentTypeEnum, String userId, Wrapper<ResponseFormat> errorWrapper) {
510 if (!ComponentValidationUtils.canWorkOnComponent(componentId, toscaOperationFacade, userId)) {
511 log.info("Restricted operation for user {} on {} {}", userId, componentTypeEnum.getValue(), componentId);
512 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
517 void validateComponentLock(String componentId, ComponentTypeEnum componentTypeEnum, Wrapper<ResponseFormat> errorWrapper) {
518 StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType());
519 if (lockStatus != StorageOperationStatus.OK) {
520 log.debug("Failed to lock {} {}", componentTypeEnum.getValue(), componentId);
521 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
526 protected ToscaPropertyType getType(String propertyType) {
527 return ToscaPropertyType.isValidType(propertyType);
530 void commitOrRollback(Either<?, ResponseFormat> result) {
531 if (result == null || result.isRight()) {
532 log.warn("operation failed. do rollback");
533 janusGraphDao.rollback();
535 log.debug("operation success. do commit");
536 janusGraphDao.commit();
540 protected Either<Boolean, ResponseFormat> lockComponentByName(String name, Component component, String ecompErrorContext) {
541 ComponentTypeEnum componentType = component.getComponentType();
542 NodeTypeEnum nodeType = componentType.getNodeType();
543 StorageOperationStatus lockResourceStatus = graphLockOperation.lockComponentByName(name, nodeType);
545 if (lockResourceStatus == StorageOperationStatus.OK) {
546 return Either.left(true);
548 BeEcompErrorManager.getInstance().logBeFailedLockObjectError(ecompErrorContext, nodeType.getName(), name);
549 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(lockResourceStatus, componentType);
550 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, component.getName());
551 log.debug(FAILED_TO_LOCK_COMPONENT_ERROR, name, actionStatus);
552 return Either.right(responseFormat);
556 protected Component validateComponentExistsByFilter(String componentId, ComponentTypeEnum componentType, ComponentParametersView componentParametersView) {
557 return toscaOperationFacade.getToscaElement(componentId, componentParametersView)
559 .on(err -> handleGetComponentError(componentId, componentType, err));
563 private Component handleGetComponentError(String componentId, ComponentTypeEnum componentType, StorageOperationStatus getComponentError) {
564 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentError, componentType);
565 log.debug("error fetching component with id {}. error status: {}", componentId, getComponentError);
566 throw new ByActionStatusComponentException(actionStatus, componentId);
570 static <T extends Enum<T>> boolean enumHasValueFilter(String name, Function<String, T> enumGetter, T... enumValues) {
571 T enumFound = enumGetter.apply(name);
572 return Arrays.asList(enumValues).contains(enumFound);
575 String validatePropValueBeforeCreate(IPropertyInputCommon property, String value, boolean isValidate,
576 Map<String, DataTypeDefinition> allDataTypes) {
577 String propertyType = property.getType();
578 String updatedInnerType = updateInnerType(property);
579 Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value, isValidate, updatedInnerType, allDataTypes);
580 String newValue = value;
581 if (isValid.isRight()) {
582 Boolean res = isValid.right().value();
583 if (Boolean.FALSE.equals(res)) {
584 throw new StorageException(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(
585 JanusGraphOperationStatus.ILLEGAL_ARGUMENT));
588 Object object = isValid.left().value();
589 if (object != null) {
590 newValue = object.toString();
593 ImmutablePair<String, Boolean> pair = validateAndUpdateRules(propertyType, property.getRules(), updatedInnerType, allDataTypes, isValidate);
594 log.trace("After validateAndUpdateRules. pair = {}", pair);
595 if (Boolean.FALSE.equals(pair.getRight())) {
596 BeEcompErrorManager.getInstance().logBeInvalidValueError(ADD_PROPERTY_VALUE, pair.getLeft(), property.getName(), propertyType);
597 throw new StorageException(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(
598 JanusGraphOperationStatus.ILLEGAL_ARGUMENT));
603 private String updateInnerType(IPropertyInputCommon property) {
604 ToscaPropertyType type = ToscaPropertyType.isValidType(property.getType());
605 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
606 SchemaDefinition def = property.getSchema();
608 log.debug(SCHEMA_DOESN_T_EXISTS_FOR_PROPERTY_OF_TYPE, type);
609 failOnIllegalArgument();
611 PropertyDataDefinition propDef = def.getProperty();
612 if (propDef == null) {
613 log.debug(PROPERTY_IN_SCHEMA_DEFINITION_INSIDE_PROPERTY_OF_TYPE_DOESN_T_EXIST, type);
614 failOnIllegalArgument();
616 return propDef.getType();
621 private void failOnIllegalArgument() {
622 throw new ByActionStatusComponentException(
623 componentsUtils.convertFromStorageResponse(
624 DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT)));
627 public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, boolean isValidate, String innerType, Map<String, DataTypeDefinition> dataTypes) {
628 log.trace("Going to validate property value and its type. type = {}, value = {}", propertyType, value);
629 ToscaPropertyType type = getType(propertyType);
634 DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
635 ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, dataTypes);
636 if (Boolean.FALSE.equals(validateResult.right)) {
637 log.debug(THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID, value, propertyType);
638 return Either.right(false);
640 JsonElement jsonElement = validateResult.left;
641 String valueFromJsonElement = getValueFromJsonElement(jsonElement);
642 return Either.left(valueFromJsonElement);
644 log.trace("before validating property type {}", propertyType);
645 boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
646 if (!isValidProperty) {
647 log.debug(THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID, value, type);
648 return Either.right(false);
651 Object convertedValue = value;
652 if (!isEmptyValue(value) && isValidate) {
653 PropertyValueConverter converter = type.getConverter();
654 convertedValue = converter.convert(value, innerType, dataTypes);
656 return Either.left(convertedValue);
659 private ImmutablePair<String, Boolean> validateAndUpdateRules(String propertyType, List<PropertyRule> rules, String innerType, Map<String, DataTypeDefinition> dataTypes, boolean isValidate) {
661 if (rules == null || rules.isEmpty()) {
662 return ImmutablePair.of(null, true);
665 for (PropertyRule rule : rules) {
666 String value = rule.getValue();
667 Either<Object, Boolean> updateResult = validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, dataTypes);
668 if (updateResult.isRight()) {
669 Boolean status = updateResult.right().value();
670 if (Boolean.FALSE.equals(status)) {
671 return ImmutablePair.of(value, status);
674 String newValue = null;
675 Object object = updateResult.left().value();
676 if (object != null) {
677 newValue = object.toString();
679 rule.setValue(newValue);
683 return ImmutablePair.of(null, true);
686 protected boolean isValidValue(ToscaPropertyType type, String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
687 if (isEmptyValue(value)) {
691 PropertyTypeValidator validator = type.getValidator();
693 return validator.isValid(value, innerType, dataTypes);
696 public boolean isEmptyValue(String value) {
697 return value == null;
700 protected String getValueFromJsonElement(JsonElement jsonElement) {
701 if (jsonElement == null || jsonElement.isJsonNull()) {
704 if (jsonElement.toString().isEmpty()) {
707 return jsonElement.toString();
710 protected void rollbackWithException(ActionStatus actionStatus, String... params) {
711 janusGraphDao.rollback();
712 throw new ByActionStatusComponentException(actionStatus, params);
715 public <T extends ToscaDataDefinition> Either<List<T>, ResponseFormat> declareProperties(String userId, String componentId,
716 ComponentTypeEnum componentTypeEnum, ComponentInstInputsMap componentInstInputsMap) {
718 return Either.left(new ArrayList<>());
721 public <T extends PropertyDataDefinition> List<PropertyConstraint> setInputConstraint(T inputDefinition) {
722 if (StringUtils.isNotBlank(inputDefinition.getParentPropertyType())
723 && StringUtils.isNotBlank(inputDefinition.getSubPropertyInputPath())) {
724 return setConstraint(inputDefinition);
727 return Collections.emptyList();
730 private <T extends PropertyDataDefinition> List<PropertyConstraint> setConstraint(T inputDefinition) {
731 List<PropertyConstraint> constraints = new ArrayList<>();
732 String[] inputPathArr = inputDefinition.getSubPropertyInputPath().split("#");
733 if (inputPathArr.length > 1) {
734 inputPathArr = ArrayUtils.remove(inputPathArr, 0);
737 Map<String, DataTypeDefinition> dataTypeDefinitionMap =
738 applicationDataTypeCache.getAll().left().value();
740 String propertyType = inputDefinition.getParentPropertyType();
742 for (String anInputPathArr : inputPathArr) {
743 if (ToscaType.isPrimitiveType(propertyType)) {
745 dataTypeDefinitionMap.get(propertyType).getConstraints());
746 } else if (!ToscaType.isCollectionType(propertyType)) {
747 propertyType = setConstraintForComplexType(dataTypeDefinitionMap, propertyType, anInputPathArr,
755 private String setConstraintForComplexType(Map<String, DataTypeDefinition> dataTypeDefinitionMap,
757 String anInputPathArr,
758 List<PropertyConstraint> constraints) {
760 List<PropertyDefinition> propertyDefinitions =
761 dataTypeDefinitionMap.get(propertyType).getProperties();
762 for (PropertyDefinition propertyDefinition : propertyDefinitions) {
763 if (propertyDefinition.getName().equals(anInputPathArr)) {
764 if (ToscaType.isPrimitiveType(propertyDefinition.getType())) {
765 constraints.addAll(propertyDefinition.safeGetConstraints());
767 type = propertyDefinition.getType();
777 protected void rollbackWithException(StorageException e) {
778 janusGraphDao.rollback();
782 protected void rollbackWithException(ComponentException e) {
783 janusGraphDao.rollback();
787 protected void unlockRollbackWithException(Component component, RuntimeException e) {
788 janusGraphDao.rollback();
789 graphLockOperation.unlockComponent(component.getUniqueId(), component.getComponentType().getNodeType());
793 protected void unlockWithCommit(Component component){
794 ComponentTypeEnum componentType = component.getComponentType();
795 NodeTypeEnum nodeType = componentType.getNodeType();
796 janusGraphDao.commit();
797 graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
800 protected ComponentInstance componentInstanceException(StorageOperationStatus storageOperationStatus) {
801 throw new StorageException(storageOperationStatus);
804 protected Component componentException(StorageOperationStatus storageOperationStatus) {
805 throw new StorageException(storageOperationStatus);
808 protected PolicyDefinition storageExceptionPolicyDefinition(StorageOperationStatus storageOperationStatus) {
809 throw new StorageException(storageOperationStatus);
812 protected PolicyDefinition componentExceptionPolicyDefinition(ResponseFormat responseFormat) {
813 throw new ByResponseFormatComponentException(responseFormat);
816 protected Component componentException(ResponseFormat responseFormat) {
817 throw new ByResponseFormatComponentException(responseFormat);
820 protected List<ComponentInstanceProperty> componentInstancePropertyListException(StorageOperationStatus storageOperationStatus) {
821 throw new StorageException(storageOperationStatus);