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 java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Collections;
32 import java.util.List;
34 import java.util.function.Function;
35 import org.apache.commons.lang3.tuple.ImmutablePair;
36 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
37 import org.openecomp.sdc.be.components.validation.UserValidations;
38 import org.openecomp.sdc.be.config.BeEcompErrorManager;
39 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
40 import org.openecomp.sdc.be.dao.api.ActionStatus;
41 import org.openecomp.sdc.be.dao.jsongraph.JanusGraphDao;
42 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao;
43 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
44 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
45 import org.openecomp.sdc.be.datatypes.elements.PropertyRule;
46 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
47 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
48 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
49 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
50 import org.openecomp.sdc.be.impl.ComponentsUtils;
51 import org.openecomp.sdc.be.model.Component;
52 import org.openecomp.sdc.be.model.ComponentInstInputsMap;
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.PropertyConstraint;
59 import org.openecomp.sdc.be.model.PropertyDefinition;
60 import org.openecomp.sdc.be.model.User;
61 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
62 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
63 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
64 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
65 import org.openecomp.sdc.be.model.operations.StorageException;
66 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
67 import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
68 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
69 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
70 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
71 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
72 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
73 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
74 import org.openecomp.sdc.be.model.operations.impl.PolicyTypeOperation;
75 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
76 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
77 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
78 import org.openecomp.sdc.be.model.tosca.ToscaType;
79 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
80 import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter;
81 import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
82 import org.openecomp.sdc.be.user.IUserBusinessLogic;
83 import org.openecomp.sdc.be.user.Role;
84 import org.openecomp.sdc.be.user.UserBusinessLogic;
85 import org.openecomp.sdc.common.datastructure.Wrapper;
86 import org.openecomp.sdc.common.log.wrappers.Logger;
87 import org.openecomp.sdc.exception.ResponseFormat;
88 import org.springframework.beans.factory.annotation.Autowired;
90 public abstract class BaseBusinessLogic {
92 private static final String FAILED_TO_LOCK_COMPONENT_ERROR = "Failed to lock component {} error - {}";
94 private static final Logger log = Logger.getLogger(BaseBusinessLogic.class.getName());
96 private static final String EMPTY_VALUE = null;
97 private static final String SCHEMA_DOESN_T_EXISTS_FOR_PROPERTY_OF_TYPE = "Schema doesn't exists for property of type {}";
98 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";
99 private static final String ADD_PROPERTY_VALUE = "Add property value";
100 private static final String THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID = "The value {} of property from type {} is invalid";
102 protected ComponentsUtils componentsUtils;
105 protected IUserBusinessLogic userAdmin;
108 protected IGraphLockOperation graphLockOperation;
111 protected JanusGraphDao janusGraphDao;
114 protected JanusGraphGenericDao janusGraphGenericDao;
117 protected IElementOperation elementDao;
120 protected IGroupOperation groupOperation;
123 IGroupInstanceOperation groupInstanceOperation;
126 protected IGroupTypeOperation groupTypeOperation;
129 protected GroupBusinessLogic groupBusinessLogic;
132 PolicyTypeOperation policyTypeOperation;
134 @javax.annotation.Resource
135 protected ArtifactsOperations artifactToscaOperation;
138 protected PropertyOperation propertyOperation;
141 protected ApplicationDataTypeCache applicationDataTypeCache;
144 protected ToscaOperationFacade toscaOperationFacade;
147 protected ApplicationDataTypeCache dataTypeCache;
150 protected InterfaceOperation interfaceOperation;
153 protected InterfaceOperationBusinessLogic interfaceOperationBusinessLogic;
156 protected InterfaceLifecycleOperation interfaceLifecycleTypeOperation;
158 @javax.annotation.Resource
159 private UserValidations userValidations;
161 DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
164 public void setUserAdmin(UserBusinessLogic userAdmin) {
165 this.userAdmin = userAdmin;
168 public void setUserValidations(UserValidations userValidations) {
169 this.userValidations = userValidations;
172 public void setComponentsUtils(ComponentsUtils componentsUtils) {
173 this.componentsUtils = componentsUtils;
176 public void setGraphLockOperation(IGraphLockOperation graphLockOperation) {
177 this.graphLockOperation = graphLockOperation;
180 public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
181 this.toscaOperationFacade = toscaOperationFacade;
184 public void setPolicyTypeOperation(PolicyTypeOperation policyTypeOperation) {
185 this.policyTypeOperation = policyTypeOperation;
188 public void setDataTypeCache(ApplicationDataTypeCache dataTypeCache) {
189 this.dataTypeCache = dataTypeCache;
192 public void setPropertyOperation(PropertyOperation propertyOperation) {
193 this.propertyOperation = propertyOperation;
196 public void setInterfaceOperation(InterfaceOperation interfaceOperation) {
197 this.interfaceOperation = interfaceOperation;
199 public void setInterfaceOperationBusinessLogic(InterfaceOperationBusinessLogic interfaceOperationBusinessLogic) {
200 this.interfaceOperationBusinessLogic = interfaceOperationBusinessLogic;
204 User validateUserNotEmpty(User user, String ecompErrorContext) {
205 return userValidations.validateUserNotEmpty(user, ecompErrorContext);
208 protected User validateUserExists(User user, String ecompErrorContext, boolean inTransaction) {
209 return userValidations.validateUserExists(user.getUserId(), ecompErrorContext, inTransaction);
212 protected void validateUserExist(String userId, String ecompErrorContext) {
213 userValidations.validateUserExist(userId, ecompErrorContext);
216 public void setGroupTypeOperation(IGroupTypeOperation groupTypeOperation) {
217 this.groupTypeOperation = groupTypeOperation;
221 Either<User, ActionStatus> validateUserExistsActionStatus(String userId, String ecompErrorContext) {
222 return userValidations.validateUserExistsActionStatus(userId, ecompErrorContext);
225 public User validateUserExists(String userId, String ecompErrorContext, boolean inTransaction) {
226 return userValidations.validateUserExists(userId, ecompErrorContext, inTransaction);
229 protected void validateUserRole(User user, List<Role> roles) {
230 userValidations.validateUserRole(user, roles);
233 protected Either<Boolean, ResponseFormat> lockComponent(Component component, String ecompErrorContext) {
234 return lockComponent(component.getUniqueId(), component, ecompErrorContext);
237 protected Either<Component, ResponseFormat> lockComponent(Component component, boolean shoulLock, String ecompErrorContext) {
238 return shoulLock ? lockComponent(component.getUniqueId(), component, ecompErrorContext)
239 .either(l -> Either.left(component), Either::right) : Either.left(component);
242 protected Either<Boolean, ResponseFormat> lockComponent(String componentId, Component component, String ecompErrorContext) {
243 return lockElement( componentId, component, ecompErrorContext)
245 .map(r -> logAndConvertError(r, component.getUniqueId(), component.getName()) );
248 protected void lockComponent(String componentId, Component component, boolean needLock, String ecompErrorContext) {
250 lockElement( componentId, component, ecompErrorContext)
252 .on(r -> logAndThrowException(r, component.getUniqueId(), component.getName()) );
256 private Boolean logAndThrowException(ActionStatus status, String componentId, String name){
257 log.debug(FAILED_TO_LOCK_COMPONENT_ERROR, componentId, status);
258 throw new ByActionStatusComponentException(status, name);
261 private ResponseFormat logAndConvertError(ActionStatus status, String componentId, String name){
262 ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, name);
263 log.debug(FAILED_TO_LOCK_COMPONENT_ERROR, componentId, status);
264 return responseFormat;
267 private Either<Boolean, ActionStatus> lockElement(String componentId, Component component, String ecompErrorContext) {
268 ComponentTypeEnum componentType = component.getComponentType();
269 NodeTypeEnum nodeType = componentType.getNodeType();
270 StorageOperationStatus lockResourceStatus = graphLockOperation.lockComponent(componentId, nodeType);
272 if (lockResourceStatus.equals(StorageOperationStatus.OK)) {
273 return Either.left(true);
275 BeEcompErrorManager.getInstance().logBeFailedLockObjectError(ecompErrorContext, nodeType.getName(), componentId);
276 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(lockResourceStatus, componentType);
277 return Either.right(actionStatus);
281 protected void unlockComponent(Either<?, ?> either, Component component, boolean inTransaction) {
282 ComponentTypeEnum componentType = component.getComponentType();
283 NodeTypeEnum nodeType = componentType.getNodeType();
284 if (!inTransaction) {
285 if (either == null || either.isRight()) {
286 janusGraphDao.rollback();
288 janusGraphDao.commit();
292 graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
295 protected void unlockComponent(Either<?, ?> either, Component component) {
296 unlockComponent(either, component, false);
298 void unlockComponentById(Either<?, ?> either, String componentId) {
299 Either<Component, StorageOperationStatus> component = toscaOperationFacade.getToscaElement(componentId);
300 if(component.isLeft()) {
301 unlockComponent(either, component.left().value(), false);
305 <T> Either<Boolean, ResponseFormat> validateJsonBody(T bodyObject, Class<T> clazz) {
306 if (bodyObject == null) {
307 log.debug("Invalid JSON received for object of type {}", clazz.getSimpleName());
308 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
310 return Either.left(true);
314 Either<ComponentTypeEnum, ResponseFormat> validateComponentType(String componentType) {
315 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
316 if (componentTypeEnum == null) {
317 log.debug("Invalid component type {}", componentType);
318 return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, componentType));
320 return Either.left(componentTypeEnum);
324 protected Either<Component, ResponseFormat> validateComponentExists(String componentId, ComponentTypeEnum componentType, ComponentParametersView filter) {
325 return toscaOperationFacade.getToscaElement(componentId, filter == null ? new ComponentParametersView() : filter)
327 .map(err -> handleGetComponentError(componentId, componentType, err))
329 .bind(cmpt -> validateComponentType(cmpt, componentType));
332 private Either<Component, ResponseFormat> validateComponentType(Component cmpt, ComponentTypeEnum componentType) {
333 if (componentType != cmpt.getComponentType()) {
334 log.debug("component {} is not of requested type {}", cmpt.getUniqueId(), componentType);
335 ActionStatus cmptNotFoundError = componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, componentType);
336 return Either.right(componentsUtils.getResponseFormat(cmptNotFoundError));
338 return Either.left(cmpt);
341 <T extends PropertyDataDefinition> Either<String, ResponseFormat> updateInputPropertyObjectValue(T property) {
342 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypesEither = dataTypeCache.getAll();
343 if (allDataTypesEither.isRight()) {
344 JanusGraphOperationStatus status = allDataTypesEither.right().value();
345 BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR);
346 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status))));
348 Map<String, DataTypeDefinition> allDataTypes = allDataTypesEither.left().value();
349 String propertyType = property.getType();
350 String innerType = getInnerType(property);
351 // Specific Update Logic
352 Either<Object, Boolean> isValid =
353 propertyOperation.validateAndUpdatePropertyValue(propertyType, (String) property.getValue(), true,
354 innerType, allDataTypes);
355 String newValue = property.getValue();
356 if (isValid.isRight()) {
357 Boolean res = isValid.right().value();
358 if (Boolean.FALSE.equals(res)) {
359 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(
360 JanusGraphOperationStatus.ILLEGAL_ARGUMENT))));
363 Object object = isValid.left().value();
364 if (object != null) {
365 newValue = object.toString();
368 return Either.left(newValue);
371 private <T extends PropertyDataDefinition> String getInnerType(T property){
372 ToscaPropertyType type = ToscaPropertyType.isValidType(property.getType());
373 log.debug("#getInnerType - The type of the property {} is {}", property.getUniqueId(), property.getType());
374 String innerType = null;
375 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
376 if (property.getSchema() == null) {
377 log.debug(SCHEMA_DOESN_T_EXISTS_FOR_PROPERTY_OF_TYPE, type);
378 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE));
380 PropertyDataDefinition innerProperty = property.getSchema().getProperty();
381 if (innerProperty == null) {
382 log.debug(PROPERTY_IN_SCHEMA_DEFINITION_INSIDE_PROPERTY_OF_TYPE_DOESN_T_EXIST, type);
383 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE));
385 innerType = innerProperty.getType();
390 public Either<Boolean, ResponseFormat> validateCanWorkOnComponent(Component component, String userId) {
391 Either<Boolean, ResponseFormat> canWork = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
392 if (component.getLifecycleState() != LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) {
393 log.debug("Component {} is not checked-out", component.getName());
397 // verify userId is not null
398 if (userId == null) {
399 log.debug("Current user userId is null");
403 // verify component last update user is the current user
404 String lastUpdaterUserId = component.getLastUpdaterUserId();
405 if (!userId.equals(lastUpdaterUserId)) {
406 log.debug("Current user is not last updater, last updater userId: {}, current user userId: {}", lastUpdaterUserId, userId);
410 // verify resource is not deleted
411 if (Boolean.TRUE.equals(component.getIsDeleted())) {
412 log.debug("Component {} is marked as deleted", component.getUniqueId());
416 return Either.left(true);
419 ComponentTypeEnum getComponentTypeByParentComponentType(ComponentTypeEnum parentComponentType) {
420 switch (parentComponentType) {
423 return ComponentTypeEnum.RESOURCE;
425 return ComponentTypeEnum.SERVICE;
433 public void setJanusGraphGenericDao(JanusGraphDao janusGraphDao) {
434 this.janusGraphDao = janusGraphDao;
437 protected Either<Map<String, DataTypeDefinition>, ResponseFormat> getAllDataTypes(ApplicationDataTypeCache applicationDataTypeCache) {
438 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes = applicationDataTypeCache.getAll();
439 if (allDataTypes.isRight()) {
440 JanusGraphOperationStatus operationStatus = allDataTypes.right().value();
441 if (operationStatus == JanusGraphOperationStatus.NOT_FOUND) {
442 BeEcompErrorManager.getInstance().logInternalDataError("FetchDataTypes", "Data types are not loaded", ErrorSeverity.ERROR);
443 return Either.right(componentsUtils.getResponseFormat(ActionStatus.DATA_TYPE_CANNOT_BE_EMPTY));
445 BeEcompErrorManager.getInstance().logInternalFlowError("FetchDataTypes", "Failed to fetch data types", ErrorSeverity.ERROR);
446 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
449 return Either.left(allDataTypes.left().value());
452 Either<Boolean, ResponseFormat> validatePropertyDefaultValue(IComplexDefaultValue property, Map<String, DataTypeDefinition> dataTypes) {
454 String innerType = null;
455 if (!propertyOperation.isPropertyTypeValid(property)) {
456 log.info("Invalid type for property {} type {}", property.getName(), property.getType());
457 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_TYPE, property.getType(), property.getName());
458 return Either.right(responseFormat);
460 type = property.getType();
461 if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
462 ImmutablePair<String, Boolean> propertyInnerTypeValid = propertyOperation.isPropertyInnerTypeValid(property, dataTypes);
463 innerType = propertyInnerTypeValid.getLeft();
464 if (!propertyInnerTypeValid.getRight()) {
465 log.info("Invalid inner type for property {} type {}, dataTypeCount {}", property.getName(), property.getType(), dataTypes.size());
466 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE, innerType, property.getName());
467 return Either.right(responseFormat);
470 if (!propertyOperation.isPropertyDefaultValueValid(property, dataTypes)) {
471 log.info("Invalid default value for property {} type {}", property.getName(), property.getType());
472 ResponseFormat responseFormat;
473 if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
474 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE, property.getName(), type, innerType,
475 property.getDefaultValue());
477 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEFAULT_VALUE, property.getName(), type,
478 property.getDefaultValue());
480 return Either.right(responseFormat);
483 return Either.left(true);
487 void handleDefaultValue(IComplexDefaultValue newAttributeDef, Map<String, DataTypeDefinition> dataTypes) {
489 ToscaPropertyType type = ToscaPropertyType.isValidType(newAttributeDef.getType());
490 PropertyValueConverter converter = type.getConverter();
492 String innerType = null;
494 SchemaDefinition schema = newAttributeDef.getSchema();
495 if (schema != null) {
496 PropertyDataDefinition prop = schema.getProperty();
497 if (schema.getProperty() != null) {
498 innerType = prop.getType();
501 String convertedValue;
502 if (newAttributeDef.getDefaultValue() != null) {
503 convertedValue = converter.convert(newAttributeDef.getDefaultValue(), innerType, dataTypes);
504 newAttributeDef.setDefaultValue(convertedValue);
508 void validateComponentTypeEnum(ComponentTypeEnum componentTypeEnum, String errorContext, Wrapper<ResponseFormat> errorWrapper) {
509 if (componentTypeEnum == null) {
510 BeEcompErrorManager.getInstance().logInvalidInputError(errorContext, "invalid component type", ErrorSeverity.INFO);
511 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
516 protected void validateCanWorkOnComponent(String componentId, ComponentTypeEnum componentTypeEnum, String userId, Wrapper<ResponseFormat> errorWrapper) {
517 if (!ComponentValidationUtils.canWorkOnComponent(componentId, toscaOperationFacade, userId)) {
518 log.info("Restricted operation for user {} on {} {}", userId, componentTypeEnum.getValue(), componentId);
519 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
524 void validateComponentLock(String componentId, ComponentTypeEnum componentTypeEnum, Wrapper<ResponseFormat> errorWrapper) {
525 StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType());
526 if (lockStatus != StorageOperationStatus.OK) {
527 log.debug("Failed to lock {} {}", componentTypeEnum.getValue(), componentId);
528 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
533 protected ToscaPropertyType getType(String propertyType) {
534 return ToscaPropertyType.isValidType(propertyType);
537 void commitOrRollback(Either<?, ResponseFormat> result) {
538 if (result == null || result.isRight()) {
539 log.warn("operation failed. do rollback");
540 janusGraphDao.rollback();
542 log.debug("operation success. do commit");
543 janusGraphDao.commit();
547 protected Either<Boolean, ResponseFormat> lockComponentByName(String name, Component component, String ecompErrorContext) {
548 ComponentTypeEnum componentType = component.getComponentType();
549 NodeTypeEnum nodeType = componentType.getNodeType();
550 StorageOperationStatus lockResourceStatus = graphLockOperation.lockComponentByName(name, nodeType);
552 if (lockResourceStatus.equals(StorageOperationStatus.OK)) {
553 return Either.left(true);
555 BeEcompErrorManager.getInstance().logBeFailedLockObjectError(ecompErrorContext, nodeType.getName(), name);
556 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(lockResourceStatus, componentType);
557 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, component.getName());
558 log.debug(FAILED_TO_LOCK_COMPONENT_ERROR, name, actionStatus);
559 return Either.right(responseFormat);
563 protected Either<Component, ResponseFormat> validateComponentExistsByFilter(String componentId, ComponentTypeEnum componentType, ComponentParametersView componentParametersView) {
564 return toscaOperationFacade.getToscaElement(componentId, componentParametersView)
566 .map(err -> handleGetComponentError(componentId, componentType, err));
570 private ResponseFormat handleGetComponentError(String componentId, ComponentTypeEnum componentType, StorageOperationStatus getComponentError) {
571 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentError, componentType);
572 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, componentId);
573 log.debug("error fetching component with id {}. error status: {}", componentId, getComponentError);
574 return responseFormat;
578 static <T extends Enum<T>> boolean enumHasValueFilter(String name, Function<String, T> enumGetter, T... enumValues) {
579 T enumFound = enumGetter.apply(name);
580 return Arrays.asList(enumValues).contains(enumFound);
583 String validatePropValueBeforeCreate(IPropertyInputCommon property, String value, boolean isValidate, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
584 String propertyType = property.getType();
585 String updatedInnerType = updateInnerType(property, innerType);
586 Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value, isValidate, updatedInnerType, allDataTypes);
587 String newValue = value;
588 if (isValid.isRight()) {
589 Boolean res = isValid.right().value();
590 if (Boolean.FALSE.equals(res)) {
591 throw new StorageException(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(
592 JanusGraphOperationStatus.ILLEGAL_ARGUMENT));
595 Object object = isValid.left().value();
596 if (object != null) {
597 newValue = object.toString();
600 ImmutablePair<String, Boolean> pair = validateAndUpdateRules(propertyType, property.getRules(), updatedInnerType, allDataTypes, isValidate);
601 log.trace("After validateAndUpdateRules. pair = {}", pair);
602 if (Boolean.FALSE.equals(pair.getRight())) {
603 BeEcompErrorManager.getInstance().logBeInvalidValueError(ADD_PROPERTY_VALUE, pair.getLeft(), property.getName(), propertyType);
604 throw new StorageException(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(
605 JanusGraphOperationStatus.ILLEGAL_ARGUMENT));
610 private String updateInnerType(IPropertyInputCommon property, String innerType) {
611 ToscaPropertyType type = ToscaPropertyType.isValidType(property.getType());
612 if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
613 SchemaDefinition def = property.getSchema();
615 log.debug(SCHEMA_DOESN_T_EXISTS_FOR_PROPERTY_OF_TYPE, type);
616 failOnIllegalArgument();
618 PropertyDataDefinition propDef = def.getProperty();
619 if (propDef == null) {
620 log.debug(PROPERTY_IN_SCHEMA_DEFINITION_INSIDE_PROPERTY_OF_TYPE_DOESN_T_EXIST, type);
621 failOnIllegalArgument();
623 return propDef.getType();
628 private void failOnIllegalArgument() {
629 throw new ByActionStatusComponentException(
630 componentsUtils.convertFromStorageResponse(
631 DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT)));
634 public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, boolean isValidate, String innerType, Map<String, DataTypeDefinition> dataTypes) {
635 log.trace("Going to validate property value and its type. type = {}, value = {}", propertyType, value);
636 ToscaPropertyType type = getType(propertyType);
641 DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType);
642 ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, dataTypes);
643 if (Boolean.FALSE.equals(validateResult.right)) {
644 log.debug(THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID, value, propertyType);
645 return Either.right(false);
647 JsonElement jsonElement = validateResult.left;
648 String valueFromJsonElement = getValueFromJsonElement(jsonElement);
649 return Either.left(valueFromJsonElement);
651 log.trace("before validating property type {}", propertyType);
652 boolean isValidProperty = isValidValue(type, value, innerType, dataTypes);
653 if (!isValidProperty) {
654 log.debug(THE_VALUE_OF_PROPERTY_FROM_TYPE_IS_INVALID, value, type);
655 return Either.right(false);
658 Object convertedValue = value;
659 if (!isEmptyValue(value) && isValidate) {
660 PropertyValueConverter converter = type.getConverter();
661 convertedValue = converter.convert(value, innerType, dataTypes);
663 return Either.left(convertedValue);
666 private ImmutablePair<String, Boolean> validateAndUpdateRules(String propertyType, List<PropertyRule> rules, String innerType, Map<String, DataTypeDefinition> dataTypes, boolean isValidate) {
668 if (rules == null || rules.isEmpty()) {
669 return ImmutablePair.of(null, true);
672 for (PropertyRule rule : rules) {
673 String value = rule.getValue();
674 Either<Object, Boolean> updateResult = validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, dataTypes);
675 if (updateResult.isRight()) {
676 Boolean status = updateResult.right().value();
677 if (Boolean.FALSE.equals(status)) {
678 return ImmutablePair.of(value, status);
681 String newValue = null;
682 Object object = updateResult.left().value();
683 if (object != null) {
684 newValue = object.toString();
686 rule.setValue(newValue);
690 return ImmutablePair.of(null, true);
693 protected boolean isValidValue(ToscaPropertyType type, String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
694 if (isEmptyValue(value)) {
698 PropertyTypeValidator validator = type.getValidator();
700 return validator.isValid(value, innerType, dataTypes);
703 public boolean isEmptyValue(String value) {
704 return value == null;
707 protected String getValueFromJsonElement(JsonElement jsonElement) {
708 if (jsonElement == null || jsonElement.isJsonNull()) {
711 if (jsonElement.toString().isEmpty()) {
714 return jsonElement.toString();
717 protected void rollbackWithException(ActionStatus actionStatus, String... params) {
718 janusGraphDao.rollback();
719 throw new ByActionStatusComponentException(actionStatus, params);
722 public <T extends ToscaDataDefinition> Either<List<T>, ResponseFormat> declareProperties(String userId, String componentId,
723 ComponentTypeEnum componentTypeEnum, ComponentInstInputsMap componentInstInputsMap) {
725 return Either.left(new ArrayList<>());
728 public <T extends PropertyDataDefinition> List<PropertyConstraint> setInputConstraint(T inputDefinition) {
729 if (StringUtils.isNotBlank(inputDefinition.getParentPropertyType())
730 && StringUtils.isNotBlank(inputDefinition.getSubPropertyInputPath())) {
731 return setConstraint(inputDefinition);
734 return Collections.emptyList();
737 private <T extends PropertyDataDefinition> List<PropertyConstraint> setConstraint(T inputDefinition) {
738 List<PropertyConstraint> constraints = new ArrayList<>();
739 String[] inputPathArr = inputDefinition.getSubPropertyInputPath().split("#");
740 if (inputPathArr.length > 1) {
741 inputPathArr = ArrayUtils.remove(inputPathArr, 0);
744 Map<String, DataTypeDefinition> dataTypeDefinitionMap =
745 applicationDataTypeCache.getAll().left().value();
747 String propertyType = inputDefinition.getParentPropertyType();
749 for (String anInputPathArr : inputPathArr) {
750 if (ToscaType.isPrimitiveType(propertyType)) {
752 dataTypeDefinitionMap.get(propertyType).getConstraints());
753 } else if (!ToscaType.isCollectionType(propertyType)) {
754 propertyType = setConstraintForComplexType(dataTypeDefinitionMap, propertyType, anInputPathArr,
762 private String setConstraintForComplexType(Map<String, DataTypeDefinition> dataTypeDefinitionMap,
764 String anInputPathArr,
765 List<PropertyConstraint> constraints) {
767 List<PropertyDefinition> propertyDefinitions =
768 dataTypeDefinitionMap.get(propertyType).getProperties();
769 for (PropertyDefinition propertyDefinition : propertyDefinitions) {
770 if (propertyDefinition.getName().equals(anInputPathArr)) {
771 if (ToscaType.isPrimitiveType(propertyDefinition.getType())) {
772 constraints.addAll(propertyDefinition.safeGetConstraints());
774 type = propertyDefinition.getType();