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