d17762fc9028c01dbb16e428840350be139e3004
[sdc.git] /
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
17 package org.openecomp.sdc.be.components.validation;
18
19 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToComponentProperty;
20
21 import com.google.common.collect.Sets;
22 import fj.data.Either;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Objects;
30 import java.util.Optional;
31 import java.util.Set;
32 import java.util.regex.Pattern;
33 import java.util.stream.Collectors;
34 import java.util.stream.Stream;
35 import org.apache.commons.collections.CollectionUtils;
36 import org.apache.commons.collections.MapUtils;
37 import org.apache.commons.lang.StringUtils;
38 import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
39 import org.openecomp.sdc.be.dao.api.ActionStatus;
40 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
41 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
42 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
43 import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition;
44 import org.openecomp.sdc.be.model.InterfaceDefinition;
45 import org.openecomp.sdc.be.model.Operation;
46 import org.openecomp.sdc.exception.ResponseFormat;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49 import org.springframework.stereotype.Component;
50
51 @Component("interfaceOperationValidation")
52 public class InterfaceOperationValidation {
53
54     private static final String TYPE_VALIDATION_REGEX = "^[a-zA-Z0-9_]{1,200}$";
55
56     private static final Logger LOGGER = LoggerFactory.getLogger(InterfaceOperationValidation.class);
57
58     public Either<Boolean, ResponseFormat> validateInterfaceOperations(
59             InterfaceDefinition inputInterfaceDefinition, org.openecomp.sdc.be.model.Component component,
60             InterfaceDefinition storedInterfaceDefinition, Map<String, InterfaceDefinition> globalInterfaceTypes,
61             boolean isUpdate) {
62
63         Either<Boolean, ResponseFormat> validateAllowedOperationCountOnLocalInterfaceType =
64                 validateAllowedOperationCountOnLocalInterfaceType(inputInterfaceDefinition, storedInterfaceDefinition,
65                         globalInterfaceTypes, isUpdate);
66         if (validateAllowedOperationCountOnLocalInterfaceType.isRight()) {
67             return validateAllowedOperationCountOnLocalInterfaceType;
68         }
69
70         Either<Boolean, ResponseFormat> validateAllowedOperationsOnGlobalInterfaceType =
71                 validateAllowedOperationsOnGlobalInterfaceType(inputInterfaceDefinition, globalInterfaceTypes);
72         if (validateAllowedOperationsOnGlobalInterfaceType.isRight()) {
73             return validateAllowedOperationsOnGlobalInterfaceType;
74         }
75
76         Either<Boolean, ResponseFormat> validateOperationNameUniqueness =
77                 validateOperationNameUniquenessInCollection(inputInterfaceDefinition.getOperationsMap().values());
78         if (validateOperationNameUniqueness.isRight()) {
79             return validateOperationNameUniqueness;
80         }
81
82         for (Operation interfaceOperation : inputInterfaceDefinition.getOperationsMap().values()) {
83             Either<Boolean, ResponseFormat> interfaceOperationValidatorResponse = validateInterfaceOperation(
84                     interfaceOperation, storedInterfaceDefinition, inputInterfaceDefinition, component, isUpdate);
85             if (interfaceOperationValidatorResponse.isRight()) {
86                 return interfaceOperationValidatorResponse;
87             }
88         }
89
90         return Either.left(Boolean.TRUE);
91     }
92
93     private Either<Boolean, ResponseFormat> validateAllowedOperationCountOnLocalInterfaceType(
94             InterfaceDefinition inputInterfaceDefinition, InterfaceDefinition storedInterfaceDefinition,
95             Map<String, InterfaceDefinition> globalInterfaceTypes, boolean isUpdate) {
96
97         boolean isInterfaceTypeExistInGlobalType =
98                 globalInterfaceTypes.values().stream().map(InterfaceDefinition::getType)
99                 .anyMatch(type -> type.equalsIgnoreCase(inputInterfaceDefinition.getType()));
100         if (!isInterfaceTypeExistInGlobalType && (inputInterfaceDefinition.getOperations().size() > 1
101                 || (!isUpdate && storedInterfaceDefinition != null
102                 && storedInterfaceDefinition.getType().equalsIgnoreCase(inputInterfaceDefinition.getType())))) {
103             return Either.right(getResponseFormatManager()
104                     .getResponseFormat(ActionStatus.INTERFACE_OPERATION_INVALID_FOR_LOCAL_TYPE,
105                             inputInterfaceDefinition.getType()));
106         }
107
108         return Either.left(Boolean.TRUE);
109     }
110
111     private Either<Boolean, ResponseFormat> validateAllowedOperationsOnGlobalInterfaceType(
112             InterfaceDefinition interfaceDefinition, Map<String, InterfaceDefinition> globalInterfaceTypes) {
113
114         if (globalInterfaceTypes != null) {
115             boolean isOperationValidOnGlobalInterfaceType = Stream.of(interfaceDefinition)
116                     .filter(interfaceDef -> globalInterfaceTypes.values().stream().anyMatch(interfaceDef1 ->
117                             interfaceDef1.getType().equalsIgnoreCase(interfaceDef.getType())))
118                     .flatMap(interfaceDef -> interfaceDef.getOperationsMap().values().stream().map(Operation::getName))
119                     .allMatch(operationName -> globalInterfaceTypes.values().stream()
120                             .flatMap(interfaceDef -> interfaceDef.getOperationsMap().keySet().stream())
121                             .anyMatch(opName -> opName.equalsIgnoreCase(operationName)));
122             if (!isOperationValidOnGlobalInterfaceType) {
123                 return Either.right(getResponseFormatManager()
124                         .getResponseFormat(ActionStatus.INTERFACE_OPERATION_INVALID_FOR_GLOBAL_TYPE,
125                                 interfaceDefinition.getType()));
126             }
127         }
128         return Either.left(Boolean.TRUE);
129     }
130
131     private Either<Boolean, ResponseFormat> validateOperationNameUniquenessInCollection(
132             Collection<Operation> operationList) {
133         HashSet<String> operationNames = new HashSet<>();
134         for (Operation operation : operationList) {
135             if (!operationNames.add(operation.getName())) {
136                 return Either.right(getResponseFormatManager()
137                                             .getResponseFormat(ActionStatus.INTERFACE_OPERATION_NAME_ALREADY_IN_USE,
138                                                     operation.getName()));
139             }
140         }
141         return Either.left(Boolean.TRUE);
142     }
143
144     private Either<Boolean, ResponseFormat> validateInterfaceOperation(Operation interfaceOperation,
145             InterfaceDefinition storedInterfaceDefinition, InterfaceDefinition inputInterfaceDefinition,
146             org.openecomp.sdc.be.model.Component component, boolean isUpdate) {
147
148         ResponseFormatManager responseFormatManager = getResponseFormatManager();
149         Either<Boolean, ResponseFormat> interfaceOperationTypeResponse =
150                 isInterfaceOperationTypeValid(interfaceOperation, responseFormatManager, storedInterfaceDefinition,
151                         isUpdate);
152         if (interfaceOperationTypeResponse.isRight()) {
153             return Either.right(interfaceOperationTypeResponse.right().value());
154         }
155
156         if (null != interfaceOperation.getInputs()
157                 && CollectionUtils.isNotEmpty(interfaceOperation.getInputs().getListToscaDataDefinition())) {
158             Either<Boolean, ResponseFormat> inputParametersResponse =
159                     validateInputParameters(interfaceOperation, responseFormatManager);
160             if (inputParametersResponse.isRight()) {
161                 return Either.right(inputParametersResponse.right().value());
162             }
163
164             Either<Boolean, ResponseFormat> inputPropertyExistInComponent =
165                     validateInputPropertyExistInComponent(interfaceOperation,
166                             inputInterfaceDefinition, component, responseFormatManager);
167             if (inputPropertyExistInComponent.isRight()) {
168                 return Either.right(inputPropertyExistInComponent.right().value());
169             }
170         }
171
172         if (null != interfaceOperation.getOutputs()
173                 && CollectionUtils.isNotEmpty(interfaceOperation.getOutputs().getListToscaDataDefinition())) {
174             Either<Boolean, ResponseFormat> outputParametersResponse =
175                     validateOutputParameters(interfaceOperation, responseFormatManager);
176             if (outputParametersResponse.isRight()) {
177                 return Either.right(outputParametersResponse.right().value());
178             }
179         }
180
181         if (MapUtils.isNotEmpty(component.getInterfaces()) && isUpdate) {
182             Either<Boolean, ResponseFormat> mappedOutputDeletedResponse =
183                     validateMappedOutputNotDeleted(interfaceOperation, component, inputInterfaceDefinition,
184                             responseFormatManager);
185             if (mappedOutputDeletedResponse.isRight()) {
186                 return Either.right(mappedOutputDeletedResponse.right().value());
187             }
188         }
189
190         return Either.left(Boolean.TRUE);
191     }
192
193
194     private Either<Boolean, ResponseFormat> validateMappedOutputNotDeleted(Operation interfaceOperation,
195             org.openecomp.sdc.be.model.Component component, InterfaceDefinition interfaceDefinition,
196             ResponseFormatManager responseFormatManager) {
197
198         List<OperationOutputDefinition> existingOperationOutputs =
199                 getInterfaceOperationOutputs(interfaceOperation.getUniqueId(), component.getInterfaces());
200         if (existingOperationOutputs.isEmpty()) {
201             return Either.left(Boolean.TRUE);
202         }
203         Set<String> existingOperationOutputNames = existingOperationOutputs.stream()
204                 .map(OperationOutputDefinition::getName)
205                 .collect(Collectors.toSet());
206
207         ListDataDefinition<OperationOutputDefinition> currentOutputs = interfaceOperation.getOutputs();
208         Set<String> currentOperationOutputNames = new HashSet<>();
209         if (currentOutputs != null && !currentOutputs.isEmpty()) {
210             currentOperationOutputNames = currentOutputs.getListToscaDataDefinition().stream()
211                     .map(OperationOutputDefinition::getName)
212                     .collect(Collectors.toSet());
213         }
214         String mappedOutputPrefix = interfaceDefinition.getType() + "." + interfaceOperation.getName();
215         Set<String> deletedOutputs = Sets.difference(existingOperationOutputNames, currentOperationOutputNames);
216         Set<String> deletedMappedOutputs = deletedOutputs.stream()
217                 .filter(deletedOutputName -> isMappedOutputDeleted(mappedOutputPrefix, deletedOutputName,
218                         component.getInterfaces()))
219                 .map(this::getOperationOutputName)
220                 .collect(Collectors.toSet());
221
222         if (CollectionUtils.isNotEmpty(deletedMappedOutputs)) {
223             return getMappedOutputErrorResponse(responseFormatManager, deletedMappedOutputs);
224         }
225         return Either.left(Boolean.TRUE);
226     }
227
228     private boolean isMappedOutputDeleted(String mappedOutputPrefix, String outputName,
229                                           Map<String, InterfaceDefinition> componentInterfaces) {
230         List<OperationInputDefinition> interfaceOperationInputs =
231                 getOtherOperationInputsOfComponent(mappedOutputPrefix, componentInterfaces);
232         return interfaceOperationInputs.stream()
233                 .anyMatch(operationInputDefinition -> operationInputDefinition.getInputId()
234                         .equals(mappedOutputPrefix + "." + outputName));
235     }
236
237     private Either<Boolean, ResponseFormat> getMappedOutputErrorResponse(ResponseFormatManager responseFormatManager,
238                                                                          Set<String> deletedMappedOutputs) {
239         String deletedOutputNameList = String.join(",", deletedMappedOutputs);
240         LOGGER.error("Cannot update name or delete interface operation output(s) '{}' mapped to an operation input",
241                 deletedOutputNameList);
242         ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
243                 .INTERFACE_OPERATION_MAPPED_OUTPUT_DELETED, deletedOutputNameList);
244         return Either.right(errorResponse);
245     }
246
247
248     protected ResponseFormatManager getResponseFormatManager() {
249         return ResponseFormatManager.getInstance();
250     }
251
252     private Either<Boolean, ResponseFormat> isInterfaceOperationTypeValid(Operation interfaceOperation,
253                                                                           ResponseFormatManager responseFormatManager,
254                                                                           InterfaceDefinition interfaceDefinition,
255                                                                           boolean isUpdate) {
256
257         Either<Boolean, ResponseFormat> operationTypeEmptyEither =
258                 isOperationTypeEmpty(responseFormatManager, interfaceOperation.getName());
259         if (operationTypeEmptyEither.isRight()) {
260             return Either.right(operationTypeEmptyEither.right().value());
261         }
262
263         Either<Boolean, ResponseFormat> operationTypeRegexValidationResponse =
264                 isOperationTypeRegexValid(responseFormatManager, interfaceOperation.getName());
265         if (operationTypeRegexValidationResponse.isRight()) {
266             return Either.right(operationTypeRegexValidationResponse.right().value());
267         }
268
269         Either<Boolean, ResponseFormat> operationTypeUniqueResponse = validateOperationTypeUnique(interfaceOperation,
270                 interfaceDefinition, isUpdate);
271         if (operationTypeUniqueResponse.isRight()) {
272             return Either.right(operationTypeUniqueResponse.right().value());
273         }
274         if (!operationTypeUniqueResponse.left().value()) {
275             LOGGER.error("Interface Operation type  {} already in use ", interfaceOperation.getName());
276             ResponseFormat errorResponse = responseFormatManager.getResponseFormat(
277                     ActionStatus.INTERFACE_OPERATION_NAME_ALREADY_IN_USE, interfaceOperation.getName());
278             return Either.right(errorResponse);
279         }
280         return Either.left(Boolean.TRUE);
281     }
282
283     private Either<Boolean, ResponseFormat> validateInputParameters(Operation interfaceOperation,
284                                                                     ResponseFormatManager responseFormatManager) {
285         if (isInputParameterNameEmpty(interfaceOperation)) {
286             LOGGER.error("Interface operation input parameter name can't be empty");
287             ResponseFormat inputResponse =
288                     responseFormatManager.getResponseFormat(ActionStatus.INTERFACE_OPERATION_INPUT_NAME_MANDATORY);
289             return Either.right(inputResponse);
290         }
291
292         Either<Boolean, Set<String>> validateInputParametersUniqueResponse =
293                 isInputParametersUnique(interfaceOperation);
294         if (validateInputParametersUniqueResponse.isRight()) {
295             LOGGER.error("Interface operation input parameter names {} already in use",
296                     validateInputParametersUniqueResponse.right().value());
297             ResponseFormat inputResponse =
298                     responseFormatManager.getResponseFormat(ActionStatus.INTERFACE_OPERATION_INPUT_NAME_ALREADY_IN_USE,
299                             validateInputParametersUniqueResponse.right().value().toString());
300             return Either.right(inputResponse);
301         }
302         return Either.left(Boolean.TRUE);
303     }
304
305     private Either<Boolean, ResponseFormat> validateOutputParameters(Operation interfaceOperation,
306                                                                      ResponseFormatManager responseFormatManager) {
307         if (isOutputParameterNameEmpty(interfaceOperation)) {
308             LOGGER.error("Interface operation output parameter name can't be empty");
309             ResponseFormat inputResponse =
310                     responseFormatManager.getResponseFormat(ActionStatus.INTERFACE_OPERATION_OUTPUT_NAME_MANDATORY);
311             return Either.right(inputResponse);
312         }
313
314         Either<Boolean, Set<String>> validateOutputParametersUniqueResponse =
315                 isOutputParametersUnique(interfaceOperation);
316         if (validateOutputParametersUniqueResponse.isRight()) {
317             LOGGER.error("Interface operation output parameter names {} already in use",
318                     validateOutputParametersUniqueResponse.right().value());
319             ResponseFormat inputResponse =
320                     responseFormatManager.getResponseFormat(ActionStatus.INTERFACE_OPERATION_OUTPUT_NAME_ALREADY_IN_USE,
321                             validateOutputParametersUniqueResponse.right().value().toString());
322             return Either.right(inputResponse);
323         }
324         return Either.left(Boolean.TRUE);
325     }
326
327     private Either<Boolean, ResponseFormat> isOperationTypeEmpty(ResponseFormatManager responseFormatManager,
328             String operationType) {
329         if (StringUtils.isEmpty(operationType)) {
330             LOGGER.error("Interface Operation type is mandatory");
331             ResponseFormat errorResponse =
332                     responseFormatManager.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NAME_MANDATORY);
333             return Either.right(errorResponse);
334         }
335         return Either.left(Boolean.TRUE);
336     }
337
338     private Either<Boolean, ResponseFormat> isOperationTypeRegexValid(ResponseFormatManager responseFormatManager,
339             String operationType) {
340         if (!isValidOperationType(operationType)) {
341             LOGGER.error("Interface Operation type {} is invalid, Operation type should not contain"
342                                  + "Special character, space, numbers and  should not be greater than 200 characters",
343                     operationType);
344             ResponseFormat errorResponse = responseFormatManager
345                                                    .getResponseFormat(ActionStatus.INTERFACE_OPERATION_NAME_INVALID,
346                                                            operationType);
347             return Either.right(errorResponse);
348         }
349         return Either.left(Boolean.TRUE);
350     }
351
352     private Either<Boolean, ResponseFormat> validateOperationTypeUnique(Operation interfaceOperation,
353             InterfaceDefinition interfaceDefinition, boolean isUpdate) {
354         boolean isOperationTypeUnique = false;
355
356         if (interfaceDefinition == null || CollectionUtils.isEmpty(interfaceDefinition.getOperationsMap().values())) {
357             return Either.left(true);
358         }
359
360         Map<String, String> operationTypes = new HashMap<>();
361         interfaceDefinition.getOperationsMap().values()
362                 .forEach(operationType -> operationTypes.put(operationType.getUniqueId(), operationType.getName()));
363
364         if (!operationTypes.values().contains(interfaceOperation.getName())) {
365             isOperationTypeUnique = true;
366         }
367         if (!isOperationTypeUnique && isUpdate) {
368             Optional<String> id = operationTypes.entrySet().stream().filter(entry -> Objects.equals(entry.getValue(),
369                     interfaceOperation.getName())).map(Map.Entry::getKey).findAny();
370             if (id.isPresent() && id.get().equalsIgnoreCase(interfaceOperation.getUniqueId())) {
371                 isOperationTypeUnique = true;
372             }
373         }
374
375         return Either.left(isOperationTypeUnique);
376     }
377
378     private Boolean isInputParameterNameEmpty(Operation operationDataDefinition) {
379         return operationDataDefinition.getInputs().getListToscaDataDefinition().stream().anyMatch(
380                 inputParam -> inputParam.getName() == null || inputParam.getName().trim().equals(StringUtils.EMPTY));
381     }
382
383
384     private Either<Boolean, Set<String>> isInputParametersUnique(Operation operationDataDefinition) {
385         Set<String> inputParamNamesSet = new HashSet<>();
386         Set<String> duplicateParamNamesToReturn = new HashSet<>();
387         operationDataDefinition.getInputs().getListToscaDataDefinition()
388                                .forEach(inputParam -> {
389                                    if (!inputParamNamesSet.add(inputParam.getName().trim())) {
390                                        duplicateParamNamesToReturn.add(inputParam.getName().trim());
391                                    }
392                                });
393         if (!duplicateParamNamesToReturn.isEmpty()) {
394             return Either.right(duplicateParamNamesToReturn);
395         }
396         return Either.left(Boolean.TRUE);
397     }
398
399     private Boolean isOutputParameterNameEmpty(Operation operationDataDefinition) {
400         return operationDataDefinition.getOutputs().getListToscaDataDefinition().stream().anyMatch(
401                 outputParam -> outputParam.getName() == null || outputParam.getName().trim().equals(StringUtils.EMPTY));
402     }
403
404     private Either<Boolean, Set<String>> isOutputParametersUnique(Operation operationDataDefinition) {
405         Set<String> outputParamNamesSet = new HashSet<>();
406         Set<String> duplicateParamNamesToReturn = new HashSet<>();
407         operationDataDefinition.getOutputs().getListToscaDataDefinition()
408                                .forEach(outputParam -> {
409                                    if (!outputParamNamesSet.add(outputParam.getName().trim())) {
410                                        duplicateParamNamesToReturn.add(outputParam.getName().trim());
411                                    }
412                                });
413         if (!duplicateParamNamesToReturn.isEmpty()) {
414             return Either.right(duplicateParamNamesToReturn);
415         }
416         return Either.left(Boolean.TRUE);
417     }
418
419     private  Either<Boolean, ResponseFormat> validateInputPropertyExistInComponent(Operation operation,
420             InterfaceDefinition inputInterfaceDefinition, org.openecomp.sdc.be.model.Component component,
421             ResponseFormatManager responseFormatManager) {
422
423         boolean isOperationInputToInputPropertyMappingValid = false;
424         boolean isOperationInputToOtherOperationOutputMappingValid = false;
425         String mappingName = "";
426         List<OperationInputDefinition> inputListToscaDataDefinition =
427                 operation.getInputs().getListToscaDataDefinition();
428         for (OperationInputDefinition inputDefinition : inputListToscaDataDefinition) {
429             if (isOperationInputMappedToComponentProperty(inputDefinition, component.getInputs())) {
430                 isOperationInputToInputPropertyMappingValid = true;
431             } else {
432                 mappingName = inputDefinition.getInputId().contains(".")
433                         ? inputDefinition.getInputId().substring(inputDefinition.getInputId().lastIndexOf(".") + 1)
434                         : inputDefinition.getInputId();
435                 break;
436             }
437         }
438         if (isOperationInputToInputPropertyMappingValid) {
439             return Either.left(Boolean.TRUE);
440         }
441
442         //Mapped property not found in the component properties.. Check in other operation output parameters of
443         // component (other operation => not having the same full name)
444         ListDataDefinition<OperationOutputDefinition> outputListDataDefinition =
445                 getOtherOperationOutputsOfComponent(inputInterfaceDefinition.getType(), operation.getName(), component);
446
447         List<OperationOutputDefinition> componentOutputsFromOtherOperations =
448                 outputListDataDefinition.getListToscaDataDefinition();
449         if (validateOutputExistsInComponent(mappingName, componentOutputsFromOtherOperations)) {
450             isOperationInputToOtherOperationOutputMappingValid = true;
451         } else {
452             //Get the output parameter display name from the full name
453             mappingName = getOperationOutputName(mappingName);
454         }
455
456         if (!isOperationInputToOtherOperationOutputMappingValid) {
457             LOGGER.error("Interface operation input parameter property {} not found in component input properties or"
458                     + " outputs of other operations.", mappingName);
459             ResponseFormat inputResponse = responseFormatManager
460                     .getResponseFormat(ActionStatus.INTERFACE_OPERATION_INPUT_PROPERTY_NOT_FOUND_IN_COMPONENT,
461                             mappingName, component.getComponentType().getValue());
462             return Either.right(inputResponse);
463         }
464         return Either.left(Boolean.TRUE);
465     }
466
467     private boolean validateOutputExistsInComponent(String mappedOutputName,
468                                                     List<OperationOutputDefinition> outputs) {
469         return outputs.stream()
470                 .anyMatch(output -> output.getName().equals(mappedOutputName));
471     }
472
473     /**
474      * Get the list of outputs of other operations of all the interfaces in the component.
475      * @param currentInterfaceName Fully qualified interface name e.g. org.test.interfaces.node.lifecycle.Abc
476      * @param currentOperationName Name entered on the operation screen e.g. create
477      * @param component VF or service
478      */
479
480     private ListDataDefinition<OperationOutputDefinition> getOtherOperationOutputsOfComponent(
481             String currentInterfaceName, String currentOperationName, org.openecomp.sdc.be.model.Component component) {
482         ListDataDefinition<OperationOutputDefinition> componentOutputs = new ListDataDefinition<>();
483         Map<String, InterfaceDefinition> componentInterfaces = component.getInterfaces();
484         if (MapUtils.isEmpty(componentInterfaces)) {
485             return componentOutputs;
486         }
487         for (Map.Entry<String, InterfaceDefinition> interfaceDefinitionEntry : componentInterfaces.entrySet()) {
488             String interfaceName = interfaceDefinitionEntry.getKey();
489             final Map<String, OperationDataDefinition> operations = interfaceDefinitionEntry.getValue().getOperations();
490             if (MapUtils.isEmpty(operations)) {
491                 continue;
492             }
493             String actualOperationIdentifier = currentInterfaceName + "." + currentOperationName;
494             for (Map.Entry<String, OperationDataDefinition> operationEntry : operations.entrySet()) {
495                 ListDataDefinition<OperationOutputDefinition> outputs = operationEntry.getValue().getOutputs();
496                 String expectedOperationIdentifier = interfaceName + "." + operationEntry.getKey();
497                 if (!actualOperationIdentifier.equals(expectedOperationIdentifier) && !outputs.isEmpty()) {
498                     outputs.getListToscaDataDefinition().forEach(componentOutputs::add);
499                 }
500             }
501         }
502         return componentOutputs;
503     }
504
505     /**
506      * Get the input definitions of other operations of the component from current as well as other interfaces.
507      * @param currentOperationIdentifier Identifier for the request operation (interface_name.operation_name)
508      * @param componentInterfaces Interfaces of the component
509      */
510     private List<OperationInputDefinition> getOtherOperationInputsOfComponent(String currentOperationIdentifier,
511                                                                               Map<String, InterfaceDefinition>
512                                                                                       componentInterfaces) {
513         List<OperationInputDefinition> otherOperationInputs = new ArrayList<>();
514         if (MapUtils.isEmpty(componentInterfaces)) {
515             return otherOperationInputs;
516         }
517         for (Map.Entry<String, InterfaceDefinition> interfaceDefinitionEntry : componentInterfaces.entrySet()) {
518             final Map<String, OperationDataDefinition> operations = interfaceDefinitionEntry.getValue().getOperations();
519             if (MapUtils.isEmpty(operations)) {
520                 continue;
521             }
522             for (Map.Entry<String, OperationDataDefinition> operationEntry : operations.entrySet()) {
523                 ListDataDefinition<OperationInputDefinition> inputs = operationEntry.getValue().getInputs();
524                 String expectedOperationIdentifier =
525                         interfaceDefinitionEntry.getValue().getType() + "." + operationEntry.getValue().getName();
526                 if (!currentOperationIdentifier.equals(expectedOperationIdentifier) && !inputs.isEmpty()) {
527                     otherOperationInputs.addAll(inputs.getListToscaDataDefinition());
528                 }
529             }
530         }
531         return otherOperationInputs;
532     }
533
534     private String getOperationOutputName(String outputName) {
535         return outputName.contains(".")
536                 ? outputName.substring(outputName.lastIndexOf(".") + 1)
537                 : outputName;
538     }
539
540     /**
541      * Get the output of an operation in an interface.
542      * @param inputOperationId Unique identifier for the request operation
543      * @param componentInterfaces Interfaces of the component
544      */
545     private List<OperationOutputDefinition> getInterfaceOperationOutputs(String inputOperationId,
546                                                                          Map<String, InterfaceDefinition>
547                                                                                  componentInterfaces) {
548         List<OperationOutputDefinition> operationOutputDefinitions = new ArrayList<>();
549         if (MapUtils.isEmpty(componentInterfaces)) {
550             return operationOutputDefinitions;
551         }
552         for (Map.Entry<String, InterfaceDefinition> interfaceDefinitionEntry : componentInterfaces.entrySet()) {
553             final Map<String, OperationDataDefinition> operations = interfaceDefinitionEntry.getValue().getOperations();
554             if (MapUtils.isEmpty(operations)) {
555                 continue;
556             }
557             for (Map.Entry<String, OperationDataDefinition> operationEntry : operations.entrySet()) {
558                 String expectedOperationId = operationEntry.getValue().getUniqueId();
559                 if (expectedOperationId.equals(inputOperationId)) {
560                     ListDataDefinition<OperationOutputDefinition> operationOutputs =
561                             operationEntry.getValue().getOutputs();
562                     return (Objects.isNull(operationOutputs) || operationOutputs.isEmpty())
563                             ? operationOutputDefinitions
564                             : operationOutputs.getListToscaDataDefinition();
565                 }
566             }
567         }
568         return operationOutputDefinitions;
569     }
570
571     private boolean isValidOperationType(String operationType) {
572         return Pattern.matches(TYPE_VALIDATION_REGEX, operationType);
573     }
574
575 }