2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.be.components.validation;
23 import fj.data.Either;
24 import org.apache.commons.lang3.tuple.ImmutablePair;
25 import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
26 import org.openecomp.sdc.be.components.impl.utils.ExceptionUtils;
27 import org.openecomp.sdc.be.config.BeEcompErrorManager;
28 import org.openecomp.sdc.be.dao.api.ActionStatus;
29 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
30 import org.openecomp.sdc.be.impl.ComponentsUtils;
31 import org.openecomp.sdc.be.model.DataTypeDefinition;
32 import org.openecomp.sdc.be.model.PropertyDefinition;
33 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
34 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
35 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
36 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
37 import org.openecomp.sdc.exception.ResponseFormat;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40 import org.springframework.stereotype.Component;
42 import java.util.List;
44 import java.util.Optional;
47 public class PropertyValidator {
49 private final PropertyOperation propertyOperation;
50 private final ComponentsUtils componentsUtils;
51 private final ApplicationDataTypeCache applicationDataTypeCache;
52 private final ExceptionUtils exceptionUtils;
53 private static final Logger log = LoggerFactory.getLogger(ResourceBusinessLogic.class);
55 public PropertyValidator(PropertyOperation propertyOperation, ComponentsUtils componentsUtils,
56 ApplicationDataTypeCache applicationDataTypeCache, ExceptionUtils exceptionUtils) {
57 this.exceptionUtils = exceptionUtils;
58 this.propertyOperation = propertyOperation;
59 this.componentsUtils = componentsUtils;
60 this.applicationDataTypeCache = applicationDataTypeCache;
63 public void thinPropertiesValidator(List<PropertyDefinition> properties,
64 List<PropertyDefinition> dbAnnotationTypeDefinitionProperties,
65 Map<String, DataTypeDefinition> allDataTypes){
66 for (PropertyDefinition property : properties) {
67 PropertyDefinition annotationTypeSpecificProperty = isPropertyInsideAnnotationTypeProperties(
68 dbAnnotationTypeDefinitionProperties, property);
69 if(annotationTypeSpecificProperty!=null){
70 verifyPropertyIsOfDefinedType(property, annotationTypeSpecificProperty, allDataTypes);
75 private void verifyPropertyIsOfDefinedType(PropertyDefinition property,
76 PropertyDefinition typeSpecificProperty,
77 Map<String, DataTypeDefinition> allDataTypes) {
78 propertyOperation.validateAndUpdatePropertyValue(typeSpecificProperty.getType(),
79 property.getValue(), typeSpecificProperty.getSchemaType(), allDataTypes)
82 exceptionUtils.rollBackAndThrow(
83 ActionStatus.INVALID_PROPERTY_TYPE, property.getType(), property.getName())
87 private PropertyDefinition isPropertyInsideAnnotationTypeProperties(
88 List<PropertyDefinition> dbAnnotationTypeDefinitionProperties, PropertyDefinition property) {
89 Optional<PropertyDefinition> optionalResult = dbAnnotationTypeDefinitionProperties.stream()
90 .filter(prop -> prop.getName()
91 .equals(property.getName()))
93 if (optionalResult.isPresent()){
94 return optionalResult.get();
96 ResponseFormat responseFormat = componentsUtils.getResponseFormat(
97 ActionStatus.PROPERTY_NOT_FOUND, property.getType(), property.getName());
98 exceptionUtils.rollBackAndThrow(responseFormat);
102 public Either<Boolean, ResponseFormat> iterateOverProperties(List<PropertyDefinition> properties){
103 Either<Boolean, ResponseFormat> eitherResult = Either.left(true);
105 String innerType = null;
106 for (PropertyDefinition property : properties) {
107 if (!propertyOperation.isPropertyTypeValid(property)) {
108 log.info("Invalid type for property {}", property);
109 ResponseFormat responseFormat = componentsUtils.getResponseFormat(
110 ActionStatus.INVALID_PROPERTY_TYPE, property.getType(), property.getName());
111 eitherResult = Either.right(responseFormat);
115 Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes = applicationDataTypeCache.getAll();
116 if (allDataTypes.isRight()) {
117 JanusGraphOperationStatus status = allDataTypes.right().value();
118 BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToGroup", "Failed to validate property. Status is " + status, BeEcompErrorManager.ErrorSeverity.ERROR);
119 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status))));
122 type = property.getType();
124 if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
125 ResponseFormat responseFormat = validateMapOrListPropertyType(property, allDataTypes.left().value());
126 if(responseFormat != null)
130 if (!propertyOperation.isPropertyDefaultValueValid(property, allDataTypes.left().value())) {
131 log.info("Invalid default value for property {}", property);
132 ResponseFormat responseFormat;
133 if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
134 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE,
135 property.getName(), type, innerType, property.getDefaultValue());
137 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEFAULT_VALUE,
138 property.getName(), type, property.getDefaultValue());
140 eitherResult = Either.right(responseFormat);
148 private ResponseFormat validateMapOrListPropertyType(PropertyDefinition property, Map<String, DataTypeDefinition> allDataTypes) {
149 ResponseFormat responseFormat = null;
150 ImmutablePair<String, Boolean> propertyInnerTypeValid = propertyOperation
151 .isPropertyInnerTypeValid(property, allDataTypes);
152 String propertyInnerType = propertyInnerTypeValid.getLeft();
153 if (!propertyInnerTypeValid.getRight().booleanValue()) {
154 log.info("Invalid inner type for property {}", property);
155 responseFormat = componentsUtils.getResponseFormat(
156 ActionStatus.INVALID_PROPERTY_INNER_TYPE, propertyInnerType, property.getName());
158 return responseFormat;