3 * ============LICENSE_START=======================================================
4 * Copyright (C) 2022 Nordix Foundation.
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.openecomp.sdc.be.components.impl.validation;
24 import fj.data.Either;
25 import java.util.List;
27 import org.apache.commons.collections.CollectionUtils;
28 import org.apache.commons.lang3.StringUtils;
29 import org.onap.sdc.tosca.datatypes.model.PropertyType;
30 import org.openecomp.sdc.be.components.impl.exceptions.ToscaFunctionExceptionSupplier;
31 import org.openecomp.sdc.be.components.impl.exceptions.ToscaGetFunctionExceptionSupplier;
32 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
33 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
34 import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition;
35 import org.openecomp.sdc.be.datatypes.enums.PropertySource;
36 import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType;
37 import org.openecomp.sdc.be.model.Component;
38 import org.openecomp.sdc.be.model.ComponentInstance;
39 import org.openecomp.sdc.be.model.DataTypeDefinition;
40 import org.openecomp.sdc.be.model.ToscaPropertyData;
41 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
42 import org.openecomp.sdc.be.model.validation.ToscaFunctionValidator;
44 @org.springframework.stereotype.Component
45 public class ToscaFunctionValidatorImpl implements ToscaFunctionValidator {
47 private final ApplicationDataTypeCache applicationDataTypeCache;
49 public ToscaFunctionValidatorImpl(final ApplicationDataTypeCache applicationDataTypeCache) {
50 this.applicationDataTypeCache = applicationDataTypeCache;
54 public <T extends PropertyDataDefinition> void validate(T property, final Component containerComponent) {
55 if (property.getToscaFunction().getType() == null) {
56 throw ToscaFunctionExceptionSupplier.missingFunctionType().get();
58 if (property.isToscaGetFunction()) {
59 validateToscaGetFunction(property, containerComponent);
63 private <T extends PropertyDataDefinition> void validateToscaGetFunction(T property, Component parentComponent) {
64 final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) property.getToscaFunction();
65 validateGetToscaFunctionAttributes(toscaGetFunction);
66 validateGetPropertySource(toscaGetFunction.getFunctionType(), toscaGetFunction.getPropertySource());
67 if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_INPUT) {
68 validateGetFunction(property, parentComponent.getInputs(), parentComponent.getModel());
71 if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_PROPERTY) {
72 if (toscaGetFunction.getPropertySource() == PropertySource.SELF) {
73 validateGetFunction(property, parentComponent.getProperties(), parentComponent.getModel());
74 } else if (toscaGetFunction.getPropertySource() == PropertySource.INSTANCE) {
75 final ComponentInstance componentInstance =
76 parentComponent.getComponentInstanceById(toscaGetFunction.getSourceUniqueId())
77 .orElseThrow(ToscaGetFunctionExceptionSupplier.instanceNotFound(toscaGetFunction.getSourceName()));
78 validateGetFunction(property, componentInstance.getProperties(), parentComponent.getModel());
83 if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_ATTRIBUTE) {
84 if (toscaGetFunction.getPropertySource() == PropertySource.SELF) {
85 validateGetFunction(property, parentComponent.getAttributes(), parentComponent.getModel());
86 } else if (toscaGetFunction.getPropertySource() == PropertySource.INSTANCE) {
87 final ComponentInstance componentInstance =
88 parentComponent.getComponentInstanceById(toscaGetFunction.getSourceUniqueId())
89 .orElseThrow(ToscaGetFunctionExceptionSupplier.instanceNotFound(toscaGetFunction.getSourceName()));
90 validateGetFunction(property, componentInstance.getAttributes(), parentComponent.getModel());
96 throw ToscaGetFunctionExceptionSupplier.functionNotSupported(toscaGetFunction.getFunctionType()).get();
99 private <T extends PropertyDataDefinition> void validateGetFunction(final T property,
100 final List<? extends ToscaPropertyData> parentProperties,
101 final String model) {
102 final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) property.getToscaFunction();
103 if (CollectionUtils.isEmpty(parentProperties)) {
104 throw ToscaGetFunctionExceptionSupplier
105 .propertyNotFoundOnTarget(toscaGetFunction.getPropertyName(), toscaGetFunction.getPropertySource(),
106 toscaGetFunction.getFunctionType()
109 final String getFunctionPropertyUniqueId = toscaGetFunction.getPropertyUniqueId();
110 ToscaPropertyData referredProperty = parentProperties.stream()
111 .filter(property1 -> getFunctionPropertyUniqueId.equals(property1.getUniqueId()))
113 .orElseThrow(ToscaGetFunctionExceptionSupplier
114 .propertyNotFoundOnTarget(toscaGetFunction.getPropertyName(), toscaGetFunction.getPropertySource()
115 , toscaGetFunction.getFunctionType())
117 if (toscaGetFunction.isSubProperty()) {
118 referredProperty = findSubProperty(referredProperty, toscaGetFunction, model);
121 if (!property.getType().equals(referredProperty.getType())) {
122 throw ToscaGetFunctionExceptionSupplier
123 .propertyTypeDiverge(toscaGetFunction.getType(), referredProperty.getType(), property.getType()).get();
125 if (PropertyType.typeHasSchema(referredProperty.getType()) && !referredProperty.getSchemaType().equals(property.getSchemaType())) {
126 throw ToscaGetFunctionExceptionSupplier
127 .propertySchemaDiverge(toscaGetFunction.getType(), referredProperty.getSchemaType(), property.getSchemaType()).get();
131 private void validateGetToscaFunctionAttributes(final ToscaGetFunctionDataDefinition toscaGetFunction) {
132 if (toscaGetFunction.getFunctionType() == null) {
133 throw ToscaGetFunctionExceptionSupplier.targetFunctionTypeNotFound().get();
135 if (toscaGetFunction.getPropertySource() == null) {
136 throw ToscaGetFunctionExceptionSupplier.targetPropertySourceNotFound(toscaGetFunction.getFunctionType()).get();
138 if (CollectionUtils.isEmpty(toscaGetFunction.getPropertyPathFromSource())) {
139 throw ToscaGetFunctionExceptionSupplier
140 .targetSourcePathNotFound(toscaGetFunction.getFunctionType()).get();
142 if (StringUtils.isEmpty(toscaGetFunction.getSourceName()) || StringUtils.isBlank(toscaGetFunction.getSourceName())) {
143 throw ToscaGetFunctionExceptionSupplier.sourceNameNotFound(toscaGetFunction.getPropertySource()).get();
145 if (StringUtils.isEmpty(toscaGetFunction.getSourceUniqueId()) || StringUtils.isBlank(toscaGetFunction.getSourceUniqueId())) {
146 throw ToscaGetFunctionExceptionSupplier.sourceIdNotFound(toscaGetFunction.getPropertySource()).get();
148 if (StringUtils.isEmpty(toscaGetFunction.getPropertyName()) || StringUtils.isBlank(toscaGetFunction.getPropertyName())) {
149 throw ToscaGetFunctionExceptionSupplier.propertyNameNotFound(toscaGetFunction.getPropertySource()).get();
151 if (StringUtils.isEmpty(toscaGetFunction.getPropertyUniqueId()) || StringUtils.isBlank(toscaGetFunction.getPropertyUniqueId())) {
152 throw ToscaGetFunctionExceptionSupplier.propertyIdNotFound(toscaGetFunction.getPropertySource()).get();
156 private void validateGetPropertySource(final ToscaGetFunctionType functionType, final PropertySource propertySource) {
157 if (functionType == ToscaGetFunctionType.GET_INPUT && propertySource != PropertySource.SELF) {
158 throw ToscaGetFunctionExceptionSupplier
159 .targetSourceNotSupported(functionType, propertySource).get();
161 if (functionType == ToscaGetFunctionType.GET_PROPERTY && !List.of(PropertySource.SELF, PropertySource.INSTANCE).contains(propertySource)) {
162 throw ToscaGetFunctionExceptionSupplier
163 .targetSourceNotSupported(functionType, propertySource).get();
167 private ToscaPropertyData findSubProperty(final ToscaPropertyData referredProperty,
168 final ToscaGetFunctionDataDefinition toscaGetFunction,
169 final String model) {
170 final Map<String, DataTypeDefinition> dataTypeMap = loadDataTypes(model);
171 final List<String> propertyPathFromSource = toscaGetFunction.getPropertyPathFromSource();
172 DataTypeDefinition dataType = dataTypeMap.get(referredProperty.getType());
173 if (dataType == null) {
174 throw ToscaGetFunctionExceptionSupplier
175 .propertyDataTypeNotFound(propertyPathFromSource.get(0), referredProperty.getType(), toscaGetFunction.getFunctionType()).get();
177 ToscaPropertyData foundProperty = referredProperty;
178 for (int i = 1; i < propertyPathFromSource.size(); i++) {
179 final String currentPropertyName = propertyPathFromSource.get(i);
180 foundProperty = dataType.getProperties().stream()
181 .filter(propertyDefinition -> currentPropertyName.equals(propertyDefinition.getName())).findFirst()
183 ToscaGetFunctionExceptionSupplier
184 .propertyNotFoundOnTarget(propertyPathFromSource.subList(0, i), toscaGetFunction.getPropertySource(),
185 toscaGetFunction.getFunctionType())
187 dataType = dataTypeMap.get(foundProperty.getType());
188 if (dataType == null) {
189 throw ToscaGetFunctionExceptionSupplier
190 .propertyDataTypeNotFound(propertyPathFromSource.subList(0, i), foundProperty.getType(),
191 toscaGetFunction.getFunctionType()).get();
194 return foundProperty;
197 private Map<String, DataTypeDefinition> loadDataTypes(String model) {
198 final Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypeEither =
199 applicationDataTypeCache.getAll(model);
200 if (dataTypeEither.isRight()) {
201 throw ToscaGetFunctionExceptionSupplier.couldNotLoadDataTypes(model).get();
203 return dataTypeEither.left().value();