Update vulnerable package dependencies
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / validation / CapabilitiesValidation.java
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.openecomp.sdc.be.components.validation;
17
18 import fj.data.Either;
19 import java.util.Collection;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.regex.Pattern;
24 import java.util.stream.Collectors;
25 import org.apache.commons.collections.CollectionUtils;
26 import org.apache.commons.collections.MapUtils;
27 import org.apache.commons.lang3.StringUtils;
28 import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
29 import org.openecomp.sdc.be.dao.api.ActionStatus;
30 import org.openecomp.sdc.be.model.CapabilityDefinition;
31 import org.openecomp.sdc.exception.ResponseFormat;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34 import org.springframework.stereotype.Component;
35
36 @Component("capabilitiesValidation")
37 public class CapabilitiesValidation {
38
39     private static final Logger LOGGER = LoggerFactory.getLogger(CapabilitiesValidation.class);
40     private static final String CAPABILITY_NOT_FOUND_IN_COMPONENT = "Capability not found in component {} ";
41     private static final Pattern NAME_VALIDATION_REGEX_PATTERN = Pattern.compile("^[a-zA-Z0-9_.]*$");
42
43     public Either<Boolean, ResponseFormat> validateCapabilities(Collection<CapabilityDefinition> capabilities,
44                                                                 org.openecomp.sdc.be.model.Component component, boolean isUpdate) {
45         for (CapabilityDefinition capabilityDefinition : capabilities) {
46             Either<Boolean, ResponseFormat> validateCapabilityResponse = validateCapability(capabilityDefinition, component, isUpdate);
47             if (validateCapabilityResponse.isRight()) {
48                 return validateCapabilityResponse;
49             }
50         }
51         return Either.left(Boolean.TRUE);
52     }
53
54     private Either<Boolean, ResponseFormat> validateCapability(CapabilityDefinition capabilityDefinition,
55                                                                org.openecomp.sdc.be.model.Component component, boolean isUpdate) {
56         ResponseFormatManager responseFormatManager = getResponseFormatManager();
57         if (isUpdate) {
58             Either<Boolean, ResponseFormat> capabilityExistValidationEither = isCapabilityExist(capabilityDefinition, responseFormatManager,
59                 component);
60             if (capabilityExistValidationEither.isRight()) {
61                 return Either.right(capabilityExistValidationEither.right().value());
62             }
63         }
64         Either<Boolean, ResponseFormat> capabilityNameValidationResponse = validateCapabilityName(capabilityDefinition, responseFormatManager,
65             component, isUpdate);
66         if (capabilityNameValidationResponse.isRight()) {
67             return Either.right(capabilityNameValidationResponse.right().value());
68         }
69         Either<Boolean, ResponseFormat> capabilityTypeEmptyEither = isCapabilityTypeEmpty(responseFormatManager, capabilityDefinition.getType());
70         if (capabilityTypeEmptyEither.isRight()) {
71             return Either.right(capabilityTypeEmptyEither.right().value());
72         }
73         Either<Boolean, ResponseFormat> capabilityOccurrencesValidationEither = validateOccurrences(capabilityDefinition, responseFormatManager);
74         if (capabilityOccurrencesValidationEither.isRight()) {
75             return Either.right(capabilityOccurrencesValidationEither.right().value());
76         }
77         return Either.left(Boolean.FALSE);
78     }
79
80     private Either<Boolean, ResponseFormat> validateOccurrences(CapabilityDefinition capabilityDefinition,
81                                                                 ResponseFormatManager responseFormatManager) {
82         String maxOccurrences = capabilityDefinition.getMaxOccurrences();
83         String minOccurrences = capabilityDefinition.getMinOccurrences();
84         if (maxOccurrences != null && minOccurrences != null) {
85             Either<Boolean, ResponseFormat> capabilityOccurrencesValidationEither = validateOccurrences(responseFormatManager, minOccurrences,
86                 maxOccurrences);
87             if (capabilityOccurrencesValidationEither.isRight()) {
88                 return Either.right(capabilityOccurrencesValidationEither.right().value());
89             }
90         }
91         return Either.left(Boolean.TRUE);
92     }
93
94     private Either<Boolean, ResponseFormat> isCapabilityExist(CapabilityDefinition definition, ResponseFormatManager responseFormatManager,
95                                                               org.openecomp.sdc.be.model.Component component) {
96         Map<String, List<CapabilityDefinition>> componentCapabilities = component.getCapabilities();
97         if (MapUtils.isEmpty(componentCapabilities)) {
98             LOGGER.error(CAPABILITY_NOT_FOUND_IN_COMPONENT, component.getUniqueId());
99             ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND, component.getUniqueId());
100             return Either.right(errorResponse);
101         }
102         List<CapabilityDefinition> capabilityDefinitionList = componentCapabilities.values().stream().flatMap(Collection::stream)
103             .collect(Collectors.toList());
104         if (CollectionUtils.isEmpty(capabilityDefinitionList)) {
105             LOGGER.error(CAPABILITY_NOT_FOUND_IN_COMPONENT, component.getUniqueId());
106             ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND, component.getUniqueId());
107             return Either.right(errorResponse);
108         }
109         boolean isCapabilityExist = capabilityDefinitionList.stream()
110             .anyMatch(capabilityDefinition -> capabilityDefinition.getUniqueId().equalsIgnoreCase(definition.getUniqueId()));
111         if (!isCapabilityExist) {
112             LOGGER.error(CAPABILITY_NOT_FOUND_IN_COMPONENT, component.getUniqueId());
113             ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND, component.getUniqueId());
114             return Either.right(errorResponse);
115         }
116         return Either.left(Boolean.TRUE);
117     }
118
119     private Either<Boolean, ResponseFormat> validateCapabilityName(CapabilityDefinition capabilityDefinition,
120                                                                    ResponseFormatManager responseFormatManager,
121                                                                    org.openecomp.sdc.be.model.Component component, boolean isUpdate) {
122         Either<Boolean, ResponseFormat> capabilityNameEmptyEither = isCapabilityNameEmpty(responseFormatManager, capabilityDefinition.getName());
123         if (capabilityNameEmptyEither.isRight()) {
124             return Either.right(capabilityNameEmptyEither.right().value());
125         }
126         Either<Boolean, ResponseFormat> capabilityNameRegexValidationResponse = isCapabilityNameRegexValid(responseFormatManager,
127             capabilityDefinition.getName());
128         if (capabilityNameRegexValidationResponse.isRight()) {
129             return Either.right(capabilityNameRegexValidationResponse.right().value());
130         }
131         Either<Boolean, ResponseFormat> operationTypeUniqueResponse = validateCapabilityNameUnique(capabilityDefinition, component, isUpdate);
132         if (operationTypeUniqueResponse.isRight()) {
133             return Either.right(operationTypeUniqueResponse.right().value());
134         }
135         if (!operationTypeUniqueResponse.left().value()) {
136             LOGGER.error("Capability name  {} already in use ", capabilityDefinition.getName());
137             ResponseFormat errorResponse = responseFormatManager
138                 .getResponseFormat(ActionStatus.CAPABILITY_NAME_ALREADY_IN_USE, capabilityDefinition.getName());
139             return Either.right(errorResponse);
140         }
141         return Either.left(Boolean.TRUE);
142     }
143
144     private Either<Boolean, ResponseFormat> isCapabilityNameEmpty(ResponseFormatManager responseFormatManager, String capabilityName) {
145         if (StringUtils.isEmpty(capabilityName)) {
146             LOGGER.error("Capability Name is mandatory");
147             ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus.CAPABILITY_NAME_MANDATORY);
148             return Either.right(errorResponse);
149         }
150         return Either.left(Boolean.TRUE);
151     }
152
153     private Either<Boolean, ResponseFormat> isCapabilityTypeEmpty(ResponseFormatManager responseFormatManager, String capabilityType) {
154         if (StringUtils.isEmpty(capabilityType)) {
155             LOGGER.error("Capability type is mandatory");
156             ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus.CAPABILITY_TYPE_MANDATORY);
157             return Either.right(errorResponse);
158         }
159         return Either.left(Boolean.TRUE);
160     }
161
162     private Either<Boolean, ResponseFormat> validateOccurrences(ResponseFormatManager responseFormatManager, String minOccurrences,
163                                                                 String maxOccurrences) {
164         try {
165             if (StringUtils.isNotEmpty(maxOccurrences) && "UNBOUNDED".equalsIgnoreCase(maxOccurrences) && Integer.parseInt(minOccurrences) >= 0) {
166                 return Either.left(Boolean.TRUE);
167             } else if (Integer.parseInt(minOccurrences) < 0) {
168                 LOGGER.debug("Invalid occurrences format.low_bound occurrence negative {}", minOccurrences);
169                 ResponseFormat responseFormat = responseFormatManager.getResponseFormat(ActionStatus.INVALID_OCCURRENCES);
170                 return Either.right(responseFormat);
171             } else if (Integer.parseInt(maxOccurrences) < Integer.parseInt(minOccurrences)) {
172                 LOGGER.error("Capability maxOccurrences should be greater than minOccurrences");
173                 ResponseFormat errorResponse = responseFormatManager
174                     .getResponseFormat(ActionStatus.MAX_OCCURRENCES_SHOULD_BE_GREATER_THAN_MIN_OCCURRENCES);
175                 return Either.right(errorResponse);
176             }
177         } catch (NumberFormatException ex) {
178             LOGGER.debug("Invalid occurrences. Only Integer allowed");
179             ResponseFormat responseFormat = responseFormatManager.getResponseFormat(ActionStatus.INVALID_OCCURRENCES);
180             return Either.right(responseFormat);
181         }
182         return Either.left(Boolean.TRUE);
183     }
184
185     private Either<Boolean, ResponseFormat> validateCapabilityNameUnique(CapabilityDefinition capabilityDefinition,
186                                                                          org.openecomp.sdc.be.model.Component component, boolean isUpdate) {
187         boolean isCapabilityNameUnique = false;
188         Map<String, List<CapabilityDefinition>> componentCapabilities = component.getCapabilities();
189         if (MapUtils.isEmpty(componentCapabilities)) {
190             return Either.left(true);
191         }
192         List<CapabilityDefinition> capabilityDefinitionList = componentCapabilities.values().stream().flatMap(Collection::stream)
193             .collect(Collectors.toList());
194         if (CollectionUtils.isEmpty(capabilityDefinitionList)) {
195             return Either.left(true);
196         }
197         Map<String, String> capabilityNameMap = new HashMap<>();
198         capabilityDefinitionList.forEach(capability -> capabilityNameMap.put(capability.getUniqueId(), capability.getName()));
199         if (!capabilityNameMap.values().contains(capabilityDefinition.getName())) {
200             isCapabilityNameUnique = true;
201         }
202         if (!isCapabilityNameUnique && isUpdate) {
203             List<Map.Entry<String, String>> capNamesEntries = capabilityNameMap.entrySet().stream()
204                 .filter(entry -> entry.getValue().equalsIgnoreCase(capabilityDefinition.getName())).collect(Collectors.toList());
205             if (capNamesEntries.size() == 1 && capNamesEntries.get(0).getKey().equals(capabilityDefinition.getUniqueId())) {
206                 isCapabilityNameUnique = true;
207             }
208         }
209         return Either.left(isCapabilityNameUnique);
210     }
211
212     private Either<Boolean, ResponseFormat> isCapabilityNameRegexValid(ResponseFormatManager responseFormatManager, String capabilityName) {
213         if (!isValidCapabilityName(capabilityName)) {
214             LOGGER.error("Capability name {} is invalid, Only alphanumeric chars, underscore and dot allowed", capabilityName);
215             ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus.INVALID_CAPABILITY_NAME, capabilityName);
216             return Either.right(errorResponse);
217         }
218         return Either.left(Boolean.TRUE);
219     }
220
221     private boolean isValidCapabilityName(String capabilityName) {
222         return NAME_VALIDATION_REGEX_PATTERN.matcher(capabilityName).matches();
223     }
224
225     protected ResponseFormatManager getResponseFormatManager() {
226         return ResponseFormatManager.getInstance();
227     }
228 }