2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2020 Nordix Foundation
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * 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 * SPDX-License-Identifier: Apache-2.0
17 * ============LICENSE_END=========================================================
20 package org.openecomp.sdc.be.components.impl;
22 import static org.openecomp.sdc.be.components.impl.ImportUtils.Constants.QUOTE;
23 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DEFAULT;
24 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DESCRIPTION;
25 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.IMPLEMENTATION;
26 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.INPUTS;
27 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.NOTIFICATIONS;
28 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.OPERATIONS;
29 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.REQUIRED;
30 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.STATUS;
31 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.TYPE;
33 import fj.data.Either;
34 import java.util.Arrays;
35 import java.util.Collections;
36 import java.util.LinkedHashMap;
37 import java.util.List;
39 import java.util.Map.Entry;
40 import java.util.Optional;
41 import java.util.stream.Collectors;
42 import org.apache.commons.collections.MapUtils;
43 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
44 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
45 import org.openecomp.sdc.be.dao.api.ActionStatus;
46 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
47 import org.openecomp.sdc.be.datatypes.elements.InputDataDefinition;
48 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
49 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
50 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
51 import org.openecomp.sdc.be.model.InputDefinition;
52 import org.openecomp.sdc.be.model.InterfaceDefinition;
53 import org.openecomp.sdc.be.tosca.utils.OperationArtifactUtil;
54 import org.openecomp.sdc.exception.ResponseFormat;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57 import org.springframework.stereotype.Component;
60 * Handles interface definition TOSCA conversions
62 @Component("interfaceDefinitionHandler")
63 public class InterfaceDefinitionHandler {
65 private static final Logger LOGGER = LoggerFactory.getLogger(InterfaceDefinitionHandler.class);
67 private final InterfaceOperationBusinessLogic interfaceOperationBusinessLogic;
69 public InterfaceDefinitionHandler(final InterfaceOperationBusinessLogic interfaceOperationBusinessLogic) {
70 this.interfaceOperationBusinessLogic = interfaceOperationBusinessLogic;
74 * Creates an interface definition based on a TOSCA map representing an interface definition.
76 * @param interfaceDefinitionToscaMap the TOSCA interface definition structure
77 * @return an interface definition representation
79 public InterfaceDefinition create(final Map<String, Object> interfaceDefinitionToscaMap) {
81 final InterfaceDefinition interfaceDefinition = new InterfaceDefinition();
83 if (interfaceDefinitionToscaMap.containsKey(TYPE.getElementName())) {
84 final Object typeObj = interfaceDefinitionToscaMap.get(TYPE.getElementName());
85 if (!(typeObj instanceof String)) {
86 throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML);
88 final String type = (String) typeObj;
89 interfaceDefinition.setType(type);
90 interfaceDefinition.setUniqueId(type.toLowerCase());
93 final Map<String, InputDefinition> inputDefinitionMap = handleInputs(interfaceDefinitionToscaMap);
94 if (!inputDefinitionMap.isEmpty()) {
95 final Map<String, InputDataDefinition> collect = inputDefinitionMap.entrySet().stream().
96 collect(Collectors.toMap(Entry::getKey, value -> new InputDataDefinition(value.getValue())));
97 interfaceDefinition.setInputs(collect);
99 final Map<String, OperationDataDefinition> operationMap;
100 if (interfaceDefinitionToscaMap.containsKey(OPERATIONS.getElementName()) || interfaceDefinitionToscaMap
101 .containsKey(NOTIFICATIONS.getElementName())) {
102 operationMap = handleOperations(interfaceDefinitionToscaMap);
103 //TODO handle notifications
105 operationMap = handleLegacyOperations(interfaceDefinitionToscaMap);
107 if (!operationMap.isEmpty()) {
108 validateOperations(interfaceDefinition.getType(), operationMap);
109 interfaceDefinition.setOperations(operationMap);
112 return interfaceDefinition;
115 private void validateOperations(final String interfaceType,
116 final Map<String, OperationDataDefinition> operationMap) {
117 if (MapUtils.isEmpty(operationMap)) {
120 Either<Map<String, InterfaceDefinition>, ResponseFormat> interfaceDefinitionMapEither =
121 interfaceOperationBusinessLogic.getAllInterfaceLifecycleTypes();
122 if (interfaceDefinitionMapEither.isRight() || MapUtils.isEmpty(interfaceDefinitionMapEither.left().value())) {
123 throw new ByActionStatusComponentException(ActionStatus.INTERFACE_UNKNOWN, interfaceType);
126 final Map<String, InterfaceDefinition> interfaceDefinitionMap = interfaceDefinitionMapEither.left().value();
127 final Optional<InterfaceDefinition> interfaceDefinitionOptional = interfaceDefinitionMap.entrySet().stream()
128 .filter(interfaceDefinitionEntry -> interfaceDefinitionEntry.getKey().equalsIgnoreCase(interfaceType))
129 .map(Entry::getValue).findFirst();
130 if (interfaceDefinitionOptional.isEmpty()) {
131 throw new ByActionStatusComponentException(ActionStatus.INTERFACE_UNKNOWN, interfaceType);
133 final InterfaceDefinition interfaceDefinition = interfaceDefinitionOptional.get();
134 operationMap.keySet().forEach(operation1 -> {
135 if (!interfaceDefinition.hasOperation(operation1)) {
136 throw new ByActionStatusComponentException(ActionStatus.INTERFACE_OPERATION_NOT_DEFINED,
137 operation1, interfaceType);
142 private Map<String, OperationDataDefinition> handleOperations(
143 final Map<String, Object> interfaceDefinitionToscaMap) {
144 if (!interfaceDefinitionToscaMap.containsKey(OPERATIONS.getElementName())) {
145 return Collections.emptyMap();
147 final Map<String, Object> operationMap =
148 (Map<String, Object>) interfaceDefinitionToscaMap.get(OPERATIONS.getElementName());
149 return operationMap.entrySet().stream()
150 .map(interfaceEntry -> createOperation(interfaceEntry.getKey(),
151 (Map<String, Object>) interfaceEntry.getValue()))
153 Collectors.toMap(OperationDataDefinition::getName, operationDataDefinition -> operationDataDefinition));
156 private Map<String, OperationDataDefinition> handleLegacyOperations(
157 final Map<String, Object> interfaceDefinitionToscaMap) {
158 final List<String> notALegacyOperationEntry = Arrays
159 .asList(OPERATIONS.getElementName(),
160 TYPE.getElementName(),
161 INPUTS.getElementName(),
162 NOTIFICATIONS.getElementName());
163 return interfaceDefinitionToscaMap.entrySet().stream()
164 .filter(interfaceEntry -> !notALegacyOperationEntry.contains(interfaceEntry.getKey()))
165 .map(interfaceEntry -> createOperation(interfaceEntry.getKey(),
166 (Map<String, Object>) interfaceEntry.getValue()))
168 Collectors.toMap(OperationDataDefinition::getName, operationDataDefinition -> operationDataDefinition));
172 private OperationDataDefinition createOperation(final String operationName,
173 final Map<String, Object> operationDefinitionMap) {
174 final OperationDataDefinition operation = new OperationDataDefinition();
175 operation.setName(operationName);
177 handleOperationImplementation(operationDefinitionMap).ifPresent(operation::setImplementation);
178 if (operationDefinitionMap.containsKey(INPUTS.getElementName())) {
179 final Map<String, Object> interfaceInputs =
180 (Map<String, Object>) operationDefinitionMap.get(INPUTS.getElementName());
181 operation.setInputs(handleInterfaceOperationInputs(interfaceInputs));
187 private ListDataDefinition<OperationInputDefinition> handleInterfaceOperationInputs(
188 final Map<String, Object> interfaceInputs) {
189 final ListDataDefinition<OperationInputDefinition> inputs = new ListDataDefinition<>();
190 for (final Entry<String, Object> interfaceInput : interfaceInputs.entrySet()) {
191 final OperationInputDefinition operationInput = new OperationInputDefinition();
192 operationInput.setName(interfaceInput.getKey());
193 if (interfaceInput.getValue() instanceof Map) {
194 final LinkedHashMap<String, Object> inputPropertyValue =
195 (LinkedHashMap<String, Object>) interfaceInput.getValue();
196 LOGGER.info("createModuleInterface: i interfaceInput.getKey() {}, {} , {} ",
197 interfaceInput.getKey(), inputPropertyValue.keySet(), inputPropertyValue.values());
198 if (inputPropertyValue.get(TYPE.getElementName()) != null) {
199 operationInput.setType(inputPropertyValue.get(TYPE.getElementName()).toString());
201 if (inputPropertyValue.get(DESCRIPTION.getElementName()) != null) {
202 operationInput.setDescription(inputPropertyValue.get(DESCRIPTION.getElementName()).toString());
204 if (inputPropertyValue.get(REQUIRED.getElementName()) != null) {
205 operationInput.setRequired(
206 Boolean.getBoolean(inputPropertyValue.get(REQUIRED.getElementName()).toString()));
208 if (inputPropertyValue.get(DEFAULT.getElementName()) != null) {
209 operationInput.setToscaDefaultValue(inputPropertyValue.get(DEFAULT.getElementName()).toString());
211 if (inputPropertyValue.get(STATUS.getElementName()) != null) {
212 operationInput.setStatus(inputPropertyValue.get(STATUS.getElementName()).toString());
215 } else if (interfaceInput.getValue() instanceof String) {
216 final String value = (String) interfaceInput.getValue();
217 operationInput.setDefaultValue(value);
218 operationInput.setToscaDefaultValue(value);
219 operationInput.setValue(value);
221 inputs.add(operationInput);
226 private Optional<ArtifactDataDefinition> handleOperationImplementation(
227 final Map<String, Object> operationDefinitionMap) {
228 if (!operationDefinitionMap.containsKey(IMPLEMENTATION.getElementName())) {
229 return Optional.empty();
231 final ArtifactDataDefinition artifactDataDefinition = new ArtifactDataDefinition();
232 final String artifactName = (String) operationDefinitionMap.get(IMPLEMENTATION.getElementName());
233 if (OperationArtifactUtil.artifactNameIsALiteralValue(artifactName)) {
234 artifactDataDefinition.setArtifactName(artifactName);
236 artifactDataDefinition.setArtifactName(QUOTE + artifactName + QUOTE);
238 return Optional.of(artifactDataDefinition);
241 private Map<String, InputDefinition> handleInputs(final Map<String, Object> interfaceDefinitionToscaMap) {
242 if (!interfaceDefinitionToscaMap.containsKey(INPUTS.getElementName())) {
243 return Collections.emptyMap();
246 final Either<Map<String, InputDefinition>, ResultStatusEnum> inputMapEither =
247 ImportUtils.getInputs(interfaceDefinitionToscaMap);
248 if (inputMapEither.isRight()) {
249 return Collections.emptyMap();
252 return inputMapEither.left().value();