Added oparent to sdc main
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / validation / NodeFilterValidator.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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  */
20
21 package org.openecomp.sdc.be.components.validation;
22
23 import com.google.common.collect.ImmutableSet;
24 import fj.data.Either;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.List;
28 import java.util.Objects;
29 import java.util.Optional;
30 import java.util.Set;
31 import org.apache.commons.lang3.StringUtils;
32 import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
33 import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
34 import org.openecomp.sdc.be.dao.api.ActionStatus;
35 import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor;
36 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
37 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
38 import org.openecomp.sdc.be.impl.ComponentsUtils;
39 import org.openecomp.sdc.be.model.ComponentInstance;
40 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
41 import org.openecomp.sdc.be.model.PropertyDefinition;
42 import org.openecomp.sdc.be.model.Service;
43 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
44 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
45 import org.openecomp.sdc.be.ui.model.UIConstraint;
46 import org.openecomp.sdc.exception.ResponseFormat;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49 import org.springframework.beans.factory.annotation.Autowired;
50 import org.springframework.stereotype.Component;
51 import org.springframework.util.CollectionUtils;
52
53 @Component("NodeFilterValidator")
54 public class NodeFilterValidator {
55
56     private static final String SOURCE = "Source";
57     public static final Set<String> comparableTypes = ImmutableSet.of(ToscaPropertyType.STRING.getType(),
58             ToscaPropertyType.INTEGER.getType(), ToscaPropertyType.FLOAT.getType());
59     public static final Set<String> schemableTypes =
60             ImmutableSet.of(ToscaPropertyType.MAP.getType(), ToscaPropertyType.LIST.getType());
61     public static final Set<String> comparableConstraintsOperators =
62             ImmutableSet.of(ConstraintConvertor.GREATER_THAN_OPERATOR, ConstraintConvertor.LESS_THAN_OPERATOR);
63
64     @Autowired
65     protected ToscaOperationFacade toscaOperationFacade;
66
67     @Autowired
68     protected ComponentsUtils componentsUtils;
69
70     private static final Logger LOGGER = LoggerFactory.getLogger(NodeFilterValidator.class);
71
72     public Either<Boolean, ResponseFormat> validateComponentInstanceExist(Service service, String componentInstanceId) {
73         if (service == null || StringUtils.isEmpty(componentInstanceId)) {
74             LOGGER.debug("Input data cannot be empty");
75             return getErrorResponse(ActionStatus.NODE_FILTER_NOT_FOUND);
76         }
77         if (CollectionUtils.isEmpty(service.getComponentInstances())) {
78             LOGGER.debug("Component Instance list is empty");
79             return getErrorResponse(ActionStatus.NODE_FILTER_NOT_FOUND);
80         }
81         boolean found =
82                 service.getComponentInstances().stream().anyMatch(ci -> ci.getUniqueId().equals(componentInstanceId));
83         if (!found) {
84             LOGGER.debug("Component Instance list is empty");
85             return getErrorResponse(ActionStatus.NODE_FILTER_NOT_FOUND);
86         }
87         return Either.left(Boolean.TRUE);
88     }
89
90     private Either<Boolean, ResponseFormat> getErrorResponse(ActionStatus actionStatus, String... variables) {
91         ResponseFormat errorResponse = ResponseFormatManager.getInstance().getResponseFormat(actionStatus, variables);
92         return Either.right(errorResponse);
93     }
94
95     public Either<Boolean, ResponseFormat> validateNodeFilter(CINodeFilterDataDefinition nodeFilter, String serviceId,
96             String complonentInstanceId) {
97         return Either.left(Boolean.TRUE);
98     }
99
100
101     public Either<Boolean, ResponseFormat> validateNodeFilter(Service parentComponent, String componentInstanceId,
102             List<String> uiConstraints, NodeFilterConstraintAction action) {
103         try {
104             for (String uiConstraint : uiConstraints) {
105                 if (NodeFilterConstraintAction.ADD != action && NodeFilterConstraintAction.UPDATE != action) {
106                     break;
107                 }
108                 UIConstraint constraint = new ConstraintConvertor().convert(uiConstraint);
109                 if (ConstraintConvertor.PROPERTY_CONSTRAINT.equals(constraint.getSourceType())) {
110                     final Either<Boolean, ResponseFormat> booleanResponseFormatEither =
111                             validatePropertyConstraint(parentComponent, componentInstanceId, constraint);
112                     if (booleanResponseFormatEither.isRight()) {
113                         return booleanResponseFormatEither;
114                     }
115                 } else if (ConstraintConvertor.STATIC_CONSTRAINT.equals(constraint.getSourceType())) {
116                     final Either<Boolean, ResponseFormat> booleanResponseFormatEither =
117                             validateStaticValueAndOperator(parentComponent, componentInstanceId, constraint);
118                     if (booleanResponseFormatEither.isRight()) {
119                         return booleanResponseFormatEither;
120                     }
121                 }
122             }
123         } catch (Exception e) {
124             LOGGER.debug("Provided constraint" + uiConstraints, e);
125             return Either.right(componentsUtils.getResponseFormat(ActionStatus.CONSTRAINT_FORMAT_INCORRECT));
126         }
127
128         return Either.left(true);
129     }
130
131     private Either<Boolean, ResponseFormat> validatePropertyConstraint(Service parentComponent,
132             String componentInstanceId, UIConstraint uiConstraint) {
133         String source = SOURCE;
134         Optional<ComponentInstance> brotherComponentInstance;
135
136         List<? extends PropertyDefinition> sourcePropertyDefinition =
137                 parentComponent.getName().equals(uiConstraint.getSourceName()) ? parentComponent.getProperties() :
138                         Collections.emptyList();
139
140
141         if (sourcePropertyDefinition.isEmpty() && !parentComponent.getName().equals(uiConstraint.getSourceName())) {
142             brotherComponentInstance = parentComponent.getComponentInstances().stream()
143                                                       .filter(componentInstance -> uiConstraint.getSourceName()
144                                                                                                .equals(componentInstance
145                                                                                                                .getName()))
146                                                       .findFirst();
147
148             if (brotherComponentInstance.isPresent()) {
149                 final List<ComponentInstanceProperty> componentInstanceProperties =
150                         parentComponent.getComponentInstancesProperties()
151                                        .get(brotherComponentInstance.get().getUniqueId());
152                 sourcePropertyDefinition =
153                         componentInstanceProperties == null ? new ArrayList<>() : componentInstanceProperties;
154             }
155         }
156
157         if (!CollectionUtils.isEmpty(sourcePropertyDefinition)) {
158             Optional<? extends PropertyDefinition> sourceSelectedProperty = sourcePropertyDefinition.stream()
159                                                                                                     .filter(property -> uiConstraint
160                                                                                                                                 .getValue()
161                                                                                                                                 .equals(property.getName()))
162                                                                                                     .findFirst();
163
164             Optional<? extends PropertyDefinition> targetComponentInstanceProperty =
165                     parentComponent.getComponentInstancesProperties().get(componentInstanceId).stream()
166                                    .filter(property -> uiConstraint.getServicePropertyName().equals(property.getName()))
167                                    .findFirst();
168
169             source = !targetComponentInstanceProperty.isPresent() ? "Target" : SOURCE;
170             if (sourceSelectedProperty.isPresent() && targetComponentInstanceProperty.isPresent()) {
171                 return validatePropertyData(uiConstraint, sourceSelectedProperty, targetComponentInstanceProperty);
172             }
173         }
174
175         String missingProperty =
176                 source.equals(SOURCE) ? uiConstraint.getValue().toString() : uiConstraint.getServicePropertyName();
177
178         return Either.right(
179                 componentsUtils.getResponseFormat(ActionStatus.MAPPED_PROPERTY_NOT_FOUND, source, missingProperty));
180     }
181
182     private Either<Boolean, ResponseFormat> validatePropertyData(UIConstraint uiConstraint,
183             Optional<? extends PropertyDefinition> sourceSelectedProperty,
184             Optional<? extends PropertyDefinition> targetComponentInstanceProperty) {
185         final PropertyDefinition sourcePropDefinition = sourceSelectedProperty.get();
186         final String sourceType = sourcePropDefinition.getType();
187         final PropertyDefinition targetPropDefinition = targetComponentInstanceProperty.get();
188         final String targetType = targetPropDefinition.getType();
189         if (sourceType.equals(targetType)) {
190             if (schemableTypes.contains(sourceType)) {
191                 final SchemaDefinition sourceSchemaDefinition = sourcePropDefinition.getSchema();
192                 final SchemaDefinition targetSchemaDefinition = targetPropDefinition.getSchema();
193                 if (!sourceSchemaDefinition.equals(targetSchemaDefinition)) {
194                     return Either.right(componentsUtils.getResponseFormat(ActionStatus.SOURCE_TARGET_SCHEMA_MISMATCH,
195                             uiConstraint.getServicePropertyName(), uiConstraint.getValue().toString()));
196                 }
197             }
198             return Either.left(Boolean.TRUE);
199         } else {
200             return Either.right(componentsUtils.getResponseFormat(ActionStatus.SOURCE_TARGET_PROPERTY_TYPE_MISMATCH,
201                     uiConstraint.getServicePropertyName(), uiConstraint.getValue().toString()));
202         }
203     }
204
205     private Either<Boolean, ResponseFormat> validateStaticValueAndOperator(Service parentComponent,
206             String componentInstanceId, UIConstraint uiConstraint) {
207         if (!(Objects.nonNull(uiConstraint) && uiConstraint.getValue() instanceof String)) {
208             return Either.left(false);
209         }
210         Optional<ComponentInstanceProperty> componentInstanceProperty =
211                 parentComponent.getComponentInstancesProperties().get(componentInstanceId).stream()
212                                .filter(property -> uiConstraint.getServicePropertyName().equals(property.getName()))
213                                .findFirst();
214
215         if (!componentInstanceProperty.isPresent()) {
216             return Either.right(componentsUtils.getResponseFormat(ActionStatus.SELECTED_PROPERTY_NOT_PRESENT,
217                     uiConstraint.getServicePropertyName()));
218         }
219         if (comparableConstraintsOperators.contains(uiConstraint.getConstraintOperator()) && !comparableTypes.contains(
220                 componentInstanceProperty.get().getType())) {
221             return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_OPERATOR_PROVIDED,
222                     uiConstraint.getServicePropertyName(), uiConstraint.getConstraintOperator()));
223         }
224
225         return isValidValueCheck(componentInstanceProperty.get().getType(), String.valueOf(uiConstraint.getValue()),
226                 uiConstraint.getServicePropertyName());
227     }
228
229     private Either<Boolean, ResponseFormat> isValidValueCheck(String type, String value, String propertyName) {
230
231         ToscaPropertyType toscaPropertyType = ToscaPropertyType.isValidType(type);
232         if (Objects.isNull(toscaPropertyType)) {
233             return Either.right(
234                     componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_PROPERTY_TYPE, type, propertyName));
235         }
236         if (toscaPropertyType.getValidator().isValid(value, null)) {
237             return Either.left(Boolean.TRUE);
238         }
239         return Either.right(
240                 componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_VALUE_PROVIDED, type, propertyName, value));
241     }
242
243
244 }
245
246