2 * Copyright © 2016-2018 European Support Limited
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.openecomp.sdc.be.components.validation;
18 import fj.data.Either;
19 import java.util.Collection;
20 import java.util.HashMap;
21 import java.util.List;
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;
36 @Component("capabilitiesValidation")
37 public class CapabilitiesValidation {
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_.]*$");
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;
51 return Either.left(Boolean.TRUE);
54 private Either<Boolean, ResponseFormat> validateCapability(CapabilityDefinition capabilityDefinition,
55 org.openecomp.sdc.be.model.Component component, boolean isUpdate) {
56 ResponseFormatManager responseFormatManager = getResponseFormatManager();
58 Either<Boolean, ResponseFormat> capabilityExistValidationEither = isCapabilityExist(capabilityDefinition, responseFormatManager,
60 if (capabilityExistValidationEither.isRight()) {
61 return Either.right(capabilityExistValidationEither.right().value());
64 Either<Boolean, ResponseFormat> capabilityNameValidationResponse = validateCapabilityName(capabilityDefinition, responseFormatManager,
66 if (capabilityNameValidationResponse.isRight()) {
67 return Either.right(capabilityNameValidationResponse.right().value());
69 Either<Boolean, ResponseFormat> capabilityTypeEmptyEither = isCapabilityTypeEmpty(responseFormatManager, capabilityDefinition.getType());
70 if (capabilityTypeEmptyEither.isRight()) {
71 return Either.right(capabilityTypeEmptyEither.right().value());
73 Either<Boolean, ResponseFormat> capabilityOccurrencesValidationEither = validateOccurrences(capabilityDefinition, responseFormatManager);
74 if (capabilityOccurrencesValidationEither.isRight()) {
75 return Either.right(capabilityOccurrencesValidationEither.right().value());
77 return Either.left(Boolean.FALSE);
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,
87 if (capabilityOccurrencesValidationEither.isRight()) {
88 return Either.right(capabilityOccurrencesValidationEither.right().value());
91 return Either.left(Boolean.TRUE);
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);
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);
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);
116 return Either.left(Boolean.TRUE);
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());
126 Either<Boolean, ResponseFormat> capabilityNameRegexValidationResponse = isCapabilityNameRegexValid(responseFormatManager,
127 capabilityDefinition.getName());
128 if (capabilityNameRegexValidationResponse.isRight()) {
129 return Either.right(capabilityNameRegexValidationResponse.right().value());
131 Either<Boolean, ResponseFormat> operationTypeUniqueResponse = validateCapabilityNameUnique(capabilityDefinition, component, isUpdate);
132 if (operationTypeUniqueResponse.isRight()) {
133 return Either.right(operationTypeUniqueResponse.right().value());
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);
141 return Either.left(Boolean.TRUE);
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);
150 return Either.left(Boolean.TRUE);
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);
159 return Either.left(Boolean.TRUE);
162 private Either<Boolean, ResponseFormat> validateOccurrences(ResponseFormatManager responseFormatManager, String minOccurrences,
163 String maxOccurrences) {
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);
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);
182 return Either.left(Boolean.TRUE);
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);
192 List<CapabilityDefinition> capabilityDefinitionList = componentCapabilities.values().stream().flatMap(Collection::stream)
193 .collect(Collectors.toList());
194 if (CollectionUtils.isEmpty(capabilityDefinitionList)) {
195 return Either.left(true);
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;
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;
209 return Either.left(isCapabilityNameUnique);
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);
218 return Either.left(Boolean.TRUE);
221 private boolean isValidCapabilityName(String capabilityName) {
222 return NAME_VALIDATION_REGEX_PATTERN.matcher(capabilityName).matches();
225 protected ResponseFormatManager getResponseFormatManager() {
226 return ResponseFormatManager.getInstance();