2 * Copyright © 2016-2020 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.
17 package org.openecomp.sdc.be.tosca;
19 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DEFAULT;
20 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.INPUTS;
21 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.OPERATIONS;
23 import com.fasterxml.jackson.annotation.JsonInclude;
24 import com.fasterxml.jackson.databind.DeserializationFeature;
25 import com.fasterxml.jackson.databind.ObjectMapper;
26 import com.fasterxml.jackson.databind.module.SimpleModule;
27 import com.google.gson.Gson;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.HashMap;
31 import java.util.List;
33 import java.util.Map.Entry;
34 import java.util.Objects;
35 import java.util.Optional;
37 import java.util.stream.Collectors;
38 import org.apache.commons.collections.MapUtils;
39 import org.apache.commons.collections4.CollectionUtils;
40 import org.apache.commons.lang3.ObjectUtils;
41 import org.apache.commons.lang3.StringUtils;
42 import org.apache.commons.lang3.math.NumberUtils;
43 import org.openecomp.sdc.be.datatypes.elements.ActivityDataDefinition;
44 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
45 import org.openecomp.sdc.be.datatypes.elements.FilterDataDefinition;
46 import org.openecomp.sdc.be.datatypes.elements.InputDataDefinition;
47 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
48 import org.openecomp.sdc.be.datatypes.elements.MilestoneDataDefinition;
49 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
50 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
51 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
52 import org.openecomp.sdc.be.datatypes.enums.ActivityTypeEnum;
53 import org.openecomp.sdc.be.datatypes.enums.ConstraintType;
54 import org.openecomp.sdc.be.datatypes.enums.MilestoneTypeEnum;
55 import org.openecomp.sdc.be.model.Component;
56 import org.openecomp.sdc.be.model.ComponentInstance;
57 import org.openecomp.sdc.be.model.DataTypeDefinition;
58 import org.openecomp.sdc.be.model.InterfaceDefinition;
59 import org.openecomp.sdc.be.model.Product;
60 import org.openecomp.sdc.be.model.PropertyDefinition;
61 import org.openecomp.sdc.be.model.tosca.constraints.EqualConstraint;
62 import org.openecomp.sdc.be.model.tosca.constraints.GreaterOrEqualConstraint;
63 import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint;
64 import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint;
65 import org.openecomp.sdc.be.model.tosca.constraints.LengthConstraint;
66 import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint;
67 import org.openecomp.sdc.be.model.tosca.constraints.LessThanConstraint;
68 import org.openecomp.sdc.be.model.tosca.constraints.MaxLengthConstraint;
69 import org.openecomp.sdc.be.model.tosca.constraints.MinLengthConstraint;
70 import org.openecomp.sdc.be.model.tosca.constraints.ValidValuesConstraint;
71 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
72 import org.openecomp.sdc.be.tosca.model.ToscaActivity;
73 import org.openecomp.sdc.be.tosca.model.ToscaArtifactDefinition;
74 import org.openecomp.sdc.be.tosca.model.ToscaInput;
75 import org.openecomp.sdc.be.tosca.model.ToscaInterfaceDefinition;
76 import org.openecomp.sdc.be.tosca.model.ToscaInterfaceNodeType;
77 import org.openecomp.sdc.be.tosca.model.ToscaInterfaceOperationImplementation;
78 import org.openecomp.sdc.be.tosca.model.ToscaLifecycleOperationDefinition;
79 import org.openecomp.sdc.be.tosca.model.ToscaMilestone;
80 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
81 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
82 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignment;
83 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignmentJsonSerializer;
84 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraint;
85 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintEqual;
86 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintGreaterOrEqual;
87 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintGreaterThan;
88 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintInRange;
89 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintLength;
90 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintLessOrEqual;
91 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintLessThan;
92 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintMaxLength;
93 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintMinLength;
94 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintValidValues;
95 import org.openecomp.sdc.be.tosca.utils.OperationArtifactUtil;
96 import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum;
97 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
98 import org.springframework.beans.factory.annotation.Autowired;
99 import org.springframework.stereotype.Service;
102 public class InterfacesOperationsConverter {
104 public static final String SELF = "SELF";
105 private static final String DERIVED_FROM_STANDARD_INTERFACE = "tosca.interfaces.node.lifecycle.Standard";
106 private static final String DERIVED_FROM_BASE_DEFAULT = "org.openecomp.interfaces.node.lifecycle.";
107 private static final String DEFAULT_HAS_UNDERSCORE = "_default";
108 private static final String DOT = ".";
109 private static final String DEFAULTP = "defaultp";
110 private static final String LOCAL_INTERFACE_TYPE = "Local";
111 private final PropertyConvertor propertyConvertor;
114 public InterfacesOperationsConverter(final PropertyConvertor propertyConvertor) {
115 this.propertyConvertor = propertyConvertor;
118 private static Object getDefaultValue(Map<String, Object> inputValueMap) {
119 Object defaultValue = null;
120 for (Map.Entry<String, Object> operationEntry : inputValueMap.entrySet()) {
121 final Object value = operationEntry.getValue();
122 if (value instanceof Map) {
123 getDefaultValue((Map<String, Object>) value);
125 final String key = operationEntry.getKey();
126 if (key.equals(DEFAULTP)) {
127 defaultValue = inputValueMap.remove(key);
133 //Remove input type and copy default value directly into the proxy node template from the node type
134 private static void handleOperationInputValue(Map<String, Object> operationsMap, String parentKey) {
135 for (Map.Entry<String, Object> operationEntry : operationsMap.entrySet()) {
136 final Object value = operationEntry.getValue();
137 final String key = operationEntry.getKey();
138 if (value instanceof Map) {
139 if (INPUTS.getElementName().equals(parentKey)) {
140 Object defaultValue = getDefaultValue((Map<String, Object>) value);
141 operationsMap.put(key, defaultValue);
143 handleOperationInputValue((Map<String, Object>) value, key);
149 private static String getLastPartOfName(String toscaResourceName) {
150 return toscaResourceName.substring(toscaResourceName.lastIndexOf(DOT) + 1);
153 private static String getInputValue(final OperationInputDefinition input) {
154 if (null != input.getToscaFunction()) {
155 return input.getToscaFunction().getJsonObjectValue().toString();
157 String inputValue = input.getValue() == null ? input.getToscaDefaultValue() : input.getValue();
158 if (inputValue != null && inputValue.contains(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName())) {
159 Gson gson = new Gson();
160 Map<String, List<String>> consumptionValue = gson.fromJson(inputValue, Map.class);
161 List<String> mappedOutputValue = consumptionValue.get(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName());
162 //Extract the interface name from the interface type
163 String interfaceType = mappedOutputValue.get(1);
164 String interfaceName = interfaceType.substring(interfaceType.lastIndexOf('.') + 1);
165 mappedOutputValue.remove(1);
166 mappedOutputValue.add(1, interfaceName);
167 inputValue = gson.toJson(consumptionValue);
172 private static String getInterfaceType(Component component, String interfaceType) {
173 if (LOCAL_INTERFACE_TYPE.equals(interfaceType)) {
174 return DERIVED_FROM_BASE_DEFAULT + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName();
176 return interfaceType;
179 private static Map<String, Object> getObjectAsMap(final Object obj) {
180 final Map<String, Object> objectAsMap;
181 if (obj instanceof Map) {
182 objectAsMap = (Map<String, Object>) obj;
184 final ObjectMapper objectMapper = new ObjectMapper();
185 final SimpleModule module = new SimpleModule("ToscaPropertyAssignmentSerializer");
186 module.addSerializer(ToscaPropertyAssignment.class, new ToscaPropertyAssignmentJsonSerializer());
187 objectMapper.registerModule(module);
188 if (obj instanceof ToscaInterfaceDefinition) {
189 //Prevent empty field serialization in interface definition
190 objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
192 objectAsMap = objectMapper.convertValue(obj, Map.class);
195 final String defaultEntry = DEFAULT.getElementName();
196 if (objectAsMap.containsKey(defaultEntry)) {
197 objectAsMap.put(DEFAULT_HAS_UNDERSCORE, objectAsMap.remove(defaultEntry));
203 * Creates the interface_types element.
205 * @param component to work on
206 * @return the added element
208 public Map<String, Object> addInterfaceTypeElement(Component component, List<String> allInterfaceTypes) {
209 if (component instanceof Product) {
212 final Map<String, InterfaceDefinition> interfaces = component.getInterfaces();
213 if (MapUtils.isEmpty(interfaces)) {
216 Map<String, Object> toscaInterfaceTypes = new HashMap<>();
217 for (InterfaceDefinition interfaceDefinition : interfaces.values()) {
218 boolean isInterfaceTypeExistInGlobalType = allInterfaceTypes.stream()
219 .anyMatch(type -> type.equalsIgnoreCase(interfaceDefinition.getType()));
220 if (!isInterfaceTypeExistInGlobalType) {
221 ToscaInterfaceNodeType toscaInterfaceType = new ToscaInterfaceNodeType();
222 toscaInterfaceType.setDerived_from(DERIVED_FROM_STANDARD_INTERFACE);
223 final Map<String, OperationDataDefinition> operations = interfaceDefinition.getOperations();
224 Map<String, Object> toscaOperations = new HashMap<>();
225 for (Map.Entry<String, OperationDataDefinition> operationEntry : operations.entrySet()) {
226 toscaOperations.put(operationEntry.getValue().getName(), null);
228 toscaInterfaceType.setOperations(toscaOperations);
229 Map<String, Object> interfacesAsMap = getObjectAsMap(toscaInterfaceType);
230 Map<String, Object> operationsMap = (Map<String, Object>) interfacesAsMap.remove(OPERATIONS.getElementName());
231 interfacesAsMap.putAll(operationsMap);
232 toscaInterfaceTypes.put(getInterfaceType(component, LOCAL_INTERFACE_TYPE), interfacesAsMap);
235 return MapUtils.isNotEmpty(toscaInterfaceTypes) ? toscaInterfaceTypes : null;
238 private boolean isArtifactPresent(final OperationDataDefinition operationDataDefinition) {
239 return operationDataDefinition.getImplementation() != null
240 && StringUtils.isNotEmpty(operationDataDefinition.getImplementation().getArtifactName());
244 * Adds the 'interfaces' element to the node type provided.
246 * @param component to work on
247 * @param nodeType to which the interfaces element will be added
249 public void addInterfaceDefinitionElement(Component component, ToscaNodeType nodeType, Map<String, DataTypeDefinition> dataTypes,
250 boolean isAssociatedComponent) {
251 if (component instanceof Product) {
254 final Map<String, InterfaceDefinition> interfaces = component.getInterfaces();
255 if (MapUtils.isEmpty(interfaces)) {
258 Map<String, Object> toscaInterfaceDefinitions = getInterfacesMap(component, dataTypes, isAssociatedComponent);
259 if (MapUtils.isNotEmpty(toscaInterfaceDefinitions)) {
260 nodeType.setInterfaces(toscaInterfaceDefinitions);
264 private Map<String, Object> getInterfacesMap(Component component, Map<String, DataTypeDefinition> dataTypes, boolean isAssociatedComponent) {
265 return getInterfacesMap(component, null, component.getInterfaces(), dataTypes, isAssociatedComponent);
268 public Map<String, Object> getInterfacesMap(final Component component, final ComponentInstance componentInstance,
269 final Map<String, InterfaceDefinition> interfaces, final Map<String, DataTypeDefinition> dataTypes,
270 final boolean isAssociatedComponent) {
271 if (MapUtils.isEmpty(interfaces)) {
274 final Map<String, Object> toscaInterfaceDefinitions = new HashMap<>();
275 for (InterfaceDefinition interfaceDefinition : interfaces.values()) {
276 handleInterfaceOperations(component, componentInstance, dataTypes, isAssociatedComponent,
277 toscaInterfaceDefinitions, interfaceDefinition);
279 return toscaInterfaceDefinitions;
282 public Map<String, Object> getInterfacesMapFromComponentInstance(final Component component, final ComponentInstance componentInstance,
283 final Map<String, DataTypeDefinition> dataTypes,
284 final boolean isAssociatedComponent) {
285 final Map<String, Object> toscaInterfaceDefinitions = new HashMap<>();
286 final ObjectMapper objectMapper = new ObjectMapper();
287 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
288 for (final Map.Entry<String, Object> interfaceEntry : componentInstance.getInterfaces().entrySet()) {
289 final InterfaceDefinition interfaceDefinition = objectMapper.convertValue(interfaceEntry.getValue(), InterfaceDefinition.class);
290 handleInterfaceOperations(component, componentInstance, dataTypes, isAssociatedComponent,
291 toscaInterfaceDefinitions, interfaceDefinition);
293 return toscaInterfaceDefinitions;
296 private void handleInterfaceOperations(final Component component, final ComponentInstance componentInstance,
297 final Map<String, DataTypeDefinition> dataTypes, final boolean isAssociatedComponent,
298 final Map<String, Object> toscaInterfaceDefinitions,
299 final InterfaceDefinition interfaceDefinition) {
300 final String interfaceType;
301 if (componentInstance != null && LOCAL_INTERFACE_TYPE.equals(interfaceDefinition.getType())) {
302 interfaceType = DERIVED_FROM_BASE_DEFAULT + componentInstance.getSourceModelName();
304 interfaceType = getInterfaceType(component, interfaceDefinition.getType());
306 final ToscaInterfaceDefinition toscaInterfaceDefinition = new ToscaInterfaceDefinition();
307 if (componentInstance == null) {
308 toscaInterfaceDefinition.setType(interfaceType);
310 final Map<String, OperationDataDefinition> operations = interfaceDefinition.getOperations();
311 final Map<String, Object> toscaOperationMap = new HashMap<>();
312 for (final Entry<String, OperationDataDefinition> operationEntry : operations.entrySet()) {
313 if (operationHasAnImplementation(operationEntry.getValue())) {
314 final ToscaLifecycleOperationDefinition toscaLifecycleOperationDefinition = new ToscaLifecycleOperationDefinition();
315 handleInterfaceOperationImplementation(component, componentInstance, isAssociatedComponent, operationEntry.getValue(),
316 toscaLifecycleOperationDefinition, dataTypes);
317 if (StringUtils.isNotEmpty(operationEntry.getValue().getDescription())) {
318 toscaLifecycleOperationDefinition.setDescription(operationEntry.getValue().getDescription());
320 fillToscaOperationInputs(operationEntry.getValue(), dataTypes, toscaLifecycleOperationDefinition);
321 fillToscaOperationMilestones(operationEntry.getValue(), dataTypes, toscaLifecycleOperationDefinition);
322 toscaOperationMap.put(operationEntry.getValue().getName(), toscaLifecycleOperationDefinition);
325 toscaInterfaceDefinition.setOperations(toscaOperationMap);
326 final Map<String, Object> interfaceInputMap = createInterfaceInputMap(interfaceDefinition, dataTypes);
327 if (MapUtils.isNotEmpty(interfaceInputMap)) {
328 toscaInterfaceDefinition.setInputs(interfaceInputMap);
330 final Map<String, Object> interfaceDefinitionAsMap = getObjectAsMap(toscaInterfaceDefinition);
331 if (interfaceDefinitionAsMap.containsKey(INPUTS.getElementName())) {
332 handleDefaults((Map<String, Object>) interfaceDefinitionAsMap.get(INPUTS.getElementName()));
334 final Map<String, Object> operationsMap = (Map<String, Object>) interfaceDefinitionAsMap.remove(OPERATIONS.getElementName());
335 handleOperationInputValue(operationsMap, interfaceType);
336 interfaceDefinitionAsMap.putAll(operationsMap);
337 toscaInterfaceDefinitions.put(getLastPartOfName(interfaceType), interfaceDefinitionAsMap);
340 private void fillToscaOperationMilestones(OperationDataDefinition operation, Map<String, DataTypeDefinition> dataTypes,
341 ToscaLifecycleOperationDefinition toscaOperation) {
342 if (Objects.isNull(operation.getMilestones()) || operation.getMilestones().isEmpty()) {
343 toscaOperation.setMilestones(null);
346 Map<String, ToscaMilestone> toscaMilestones = new HashMap<>();
347 for (Entry<String, MilestoneDataDefinition> milestone : operation.getMilestones().entrySet()) {
348 ListDataDefinition<ActivityDataDefinition> activities = milestone.getValue().getActivities();
349 if (MilestoneTypeEnum.getEnum(milestone.getKey()).isEmpty() || activities == null || activities.isEmpty()) {
352 List<Map<String, ToscaActivity>> toscaActivities = new ArrayList<>();
353 for (ActivityDataDefinition activity : activities.getListToscaDataDefinition()) {
354 if (ActivityTypeEnum.getEnum(activity.getType()).isEmpty()) {
357 Map<String, ToscaActivity> toscaActivityMap = new HashMap<>();
358 ToscaActivity toscaActivity = new ToscaActivity();
359 toscaActivity.setWorkflow(activity.getWorkflow());
360 Map<String, Object> inputs = getToscaActivityInputs(activity.getInputs(), dataTypes);
361 if (MapUtils.isNotEmpty(inputs)) {
362 toscaActivity.setInputs(inputs);
364 toscaActivityMap.put(activity.getType(), toscaActivity);
365 toscaActivities.add(toscaActivityMap);
367 ToscaMilestone toscaMilestone = new ToscaMilestone();
368 toscaMilestone.setActivities(toscaActivities);
369 toscaMilestone.setFilters(getToscaFilters(milestone.getValue().getFilters()));
370 toscaMilestones.put(milestone.getKey(), toscaMilestone);
372 toscaOperation.setMilestones(toscaMilestones);
375 private List<Map<String, ToscaPropertyConstraint>> getToscaFilters(ListDataDefinition<FilterDataDefinition> filters) {
376 if (filters != null && !filters.isEmpty()) {
377 List<Map<String, ToscaPropertyConstraint>> toscaFilters = new ArrayList<>();
378 for (FilterDataDefinition filter : filters.getListToscaDataDefinition()) {
379 Optional<ConstraintType> typeOptional = ConstraintType.findByType(filter.getConstraint());
380 if (typeOptional.isEmpty()) {
383 ConstraintType type = typeOptional.get();
384 Object value = filter.isToscaFunction() ? filter.getToscaFunction().getJsonObjectValue() : filter.getFilterValue();
385 if (ConstraintType.EQUAL.equals(type)) {
386 EqualConstraint equalConstraint = new EqualConstraint(value);
387 ToscaPropertyConstraint prop = new ToscaPropertyConstraintEqual(equalConstraint.getEqual());
388 toscaFilters.add(Map.of(filter.getName(), prop));
390 if (ConstraintType.GREATER_THAN.equals(type)) {
391 GreaterThanConstraint greaterThanConstraint = new GreaterThanConstraint(value);
392 ToscaPropertyConstraintGreaterThan prop = new ToscaPropertyConstraintGreaterThan(greaterThanConstraint.getGreaterThan());
393 toscaFilters.add(Map.of(filter.getName(), prop));
395 if (ConstraintType.GREATER_OR_EQUAL.equals(type)) {
396 GreaterOrEqualConstraint greaterOrEqualConstraint = new GreaterOrEqualConstraint<>(value);
397 ToscaPropertyConstraintGreaterOrEqual prop =
398 new ToscaPropertyConstraintGreaterOrEqual(greaterOrEqualConstraint.getGreaterOrEqual());
399 toscaFilters.add(Map.of(filter.getName(), prop));
401 if (ConstraintType.LESS_THAN.equals(type)) {
402 LessThanConstraint lessThanConstraint = new LessThanConstraint(value);
403 ToscaPropertyConstraintLessThan prop = new ToscaPropertyConstraintLessThan(lessThanConstraint.getLessThan());
404 toscaFilters.add(Map.of(filter.getName(), prop));
406 if (ConstraintType.LESS_OR_EQUAL.equals(type)) {
407 LessOrEqualConstraint lessOrEqualConstraint = new LessOrEqualConstraint<>(value);
408 ToscaPropertyConstraintLessOrEqual prop = new ToscaPropertyConstraintLessOrEqual(lessOrEqualConstraint.getLessOrEqual());
409 toscaFilters.add(Map.of(filter.getName(), prop));
411 if (ConstraintType.IN_RANGE.equals(type)) {
412 InRangeConstraint inRangeConstraint = new InRangeConstraint((List<Object>) value);
413 toscaFilters.add(Map.of(filter.getName(), new ToscaPropertyConstraintInRange(inRangeConstraint.getInRange())));
415 if (ConstraintType.VALID_VALUES.equals(type)) {
416 ValidValuesConstraint validValues = new ValidValuesConstraint((List<Object>) value);
417 List prop = validValues.getValidValues();
418 toscaFilters.add(Map.of(filter.getName(), (new ToscaPropertyConstraintValidValues(prop))));
420 if (ConstraintType.LENGTH.equals(type)) {
421 LengthConstraint lengthConstraint = new LengthConstraint((Integer) value);
422 toscaFilters.add(Map.of(filter.getName(), (new ToscaPropertyConstraintLength(lengthConstraint.getLength()))));
424 if (ConstraintType.MIN_LENGTH.equals(type)) {
425 MinLengthConstraint minLengthConstraint = new MinLengthConstraint((Integer) value);
426 toscaFilters.add(Map.of(filter.getName(), new ToscaPropertyConstraintMinLength(minLengthConstraint.getMinLength())));
428 if (ConstraintType.MAX_LENGTH.equals(type)) {
429 MaxLengthConstraint maxLengthConstraint = new MaxLengthConstraint((Integer) value);
430 toscaFilters.add(Map.of(filter.getName(), new ToscaPropertyConstraintMaxLength(maxLengthConstraint.getMaxLength())));
438 private Map<String, Object> getToscaActivityInputs(ListDataDefinition<OperationInputDefinition> inputs,
439 Map<String, DataTypeDefinition> dataTypes) {
440 if (Objects.isNull(inputs) || inputs.isEmpty()) {
443 Map<String, Object> toscaInputs = new HashMap<>();
444 for (OperationInputDefinition input : inputs.getListToscaDataDefinition()) {
445 Object value = propertyConvertor.convertToToscaObject(input, getInputValue(input), dataTypes, false);
446 if (ObjectUtils.isNotEmpty(value)) {
447 toscaInputs.put(input.getName(), value);
453 private boolean operationHasAnImplementation(OperationDataDefinition operation) {
454 return operation.getImplementation() != null && StringUtils.isNotEmpty(operation.getImplementation().getArtifactName()) &&
455 !operation.getImplementation().getArtifactName().equals("''");
458 private void handleInterfaceOperationImplementation(final Component component, final ComponentInstance componentInstance,
459 final boolean isAssociatedComponent,
460 final OperationDataDefinition operationDataDefinition,
461 final ToscaLifecycleOperationDefinition toscaOperation,
462 final Map<String, DataTypeDefinition> dataTypes) {
463 final ArtifactDataDefinition implementation = operationDataDefinition.getImplementation();
464 if (implementation == null) {
468 if (isArtifactPresent(operationDataDefinition)) {
469 final String operationArtifactPath =
470 OperationArtifactUtil.createOperationArtifactPath(component, componentInstance, operationDataDefinition, isAssociatedComponent);
471 final ToscaInterfaceOperationImplementation toscaInterfaceOperationImplementation = new ToscaInterfaceOperationImplementation();
472 if (implementation.getTimeout() != null && implementation.getTimeout() > 0) {
473 toscaInterfaceOperationImplementation.setTimeout(implementation.getTimeout());
475 if (implementation.getArtifactType() != null) {
476 final ToscaArtifactDefinition toscaArtifactDefinition = new ToscaArtifactDefinition();
477 toscaArtifactDefinition.setFile(operationArtifactPath);
478 final String artifactVersion = implementation.getArtifactVersion();
479 toscaArtifactDefinition.setArtifact_version(!artifactVersion.equals(NumberUtils.INTEGER_ZERO.toString()) ? artifactVersion : null);
480 toscaArtifactDefinition.setType(implementation.getArtifactType());
481 final Map<String, ToscaPropertyAssignment> propertiesMap = handleImplementationProperties(operationDataDefinition, dataTypes);
482 if (MapUtils.isNotEmpty(propertiesMap)) {
483 toscaArtifactDefinition.setProperties(propertiesMap);
485 toscaInterfaceOperationImplementation.setPrimary(toscaArtifactDefinition);
486 toscaOperation.setImplementation(toscaInterfaceOperationImplementation);
488 if (toscaInterfaceOperationImplementation.getTimeout() != null) {
489 final ToscaArtifactDefinition toscaArtifactDefinition = new ToscaArtifactDefinition();
490 toscaArtifactDefinition.setFile(
491 StringUtils.isBlank(operationArtifactPath) || "null".equals(operationArtifactPath) ? null : operationArtifactPath);
492 toscaInterfaceOperationImplementation.setPrimary(toscaArtifactDefinition);
493 toscaOperation.setImplementation(toscaInterfaceOperationImplementation);
495 toscaOperation.setImplementation(
496 StringUtils.isBlank(operationArtifactPath) || "null".equals(operationArtifactPath) ? null : operationArtifactPath);
502 private Map<String, ToscaPropertyAssignment> handleImplementationProperties(final OperationDataDefinition operationDataDefinition,
503 final Map<String, DataTypeDefinition> dataTypes) {
504 if (operationDataDefinition.getImplementation() == null) {
505 return new HashMap<>();
508 final List<PropertyDataDefinition> properties = operationDataDefinition.getImplementation().getProperties();
509 if (CollectionUtils.isEmpty(properties)) {
510 return new HashMap<>();
513 final Map<String, ToscaPropertyAssignment> propertiesMap = new HashMap<>();
515 .filter(propertyDataDefinition -> StringUtils.isNotEmpty(propertyDataDefinition.getValue()))
516 .forEach(propertyDataDefinition -> {
517 final String propertyValue =
518 propertyDataDefinition.getValue() != null ? propertyDataDefinition.getValue() : propertyDataDefinition.getDefaultValue();
519 final ToscaPropertyAssignment toscaPropertyAssignment = new ToscaPropertyAssignment();
520 toscaPropertyAssignment.setValue(propertyConvertor.convertToToscaObject(propertyDataDefinition, propertyValue, dataTypes, false));
521 propertiesMap.put(propertyDataDefinition.getName(), toscaPropertyAssignment);
525 return propertiesMap;
528 public void removeInterfacesWithoutOperations(final Map<String, Object> interfaceMap) {
529 if (MapUtils.isEmpty(interfaceMap)) {
532 final Set<String> emptyInterfaces = interfaceMap.entrySet().stream().filter(entry -> {
533 final Object value = entry.getValue();
534 if (value instanceof ToscaInterfaceDefinition) {
535 final ToscaInterfaceDefinition interfaceDefinition = (ToscaInterfaceDefinition) value;
536 return MapUtils.isEmpty(interfaceDefinition.getOperations());
537 } else if (value instanceof Map) {
538 final Map<String, Object> interfaceDefMap = (Map<String, Object>) value;
539 return MapUtils.isEmpty(interfaceDefMap);
542 }).map(Entry::getKey).collect(Collectors.toSet());
543 emptyInterfaces.forEach(interfaceMap::remove);
546 private Map<String, Object> createInterfaceInputMap(final InterfaceDefinition interfaceDefinition,
547 final Map<String, DataTypeDefinition> allDataTypeMap) {
548 final Map<String, InputDataDefinition> inputMap = interfaceDefinition.getInputs();
549 if (MapUtils.isEmpty(inputMap)) {
550 return Collections.emptyMap();
552 final Map<String, Object> toscaInterfaceInputMap = new HashMap<>();
553 for (final Entry<String, InputDataDefinition> inputEntry : inputMap.entrySet()) {
554 final InputDataDefinition inputDataDefinition = inputEntry.getValue();
555 final ToscaProperty toscaProperty = propertyConvertor
556 .convertProperty(allDataTypeMap, new PropertyDefinition(inputDataDefinition), PropertyType.INPUT);
557 toscaInterfaceInputMap.put(inputEntry.getKey(), new ToscaInput(toscaProperty));
559 return toscaInterfaceInputMap;
563 * workaround for : currently "defaultp" is not being converted to "default" by the relevant code in
564 * ToscaExportHandler so, any string Map key named "defaultp" will have its named changed to "default"
565 * @param operationsMap the map to update
567 private void handleDefaults(Map<String, Object> operationsMap) {
568 for (Map.Entry<String, Object> operationEntry : operationsMap.entrySet()) {
569 final Object value = operationEntry.getValue();
570 if (value instanceof Map) {
571 handleDefaults((Map<String, Object>) value);
573 final String key = operationEntry.getKey();
574 if (key.equals(DEFAULTP)) {
575 Object removed = operationsMap.remove(key);
576 operationsMap.put(ToscaTagNamesEnum.DEFAULT.getElementName(), removed);
581 private void fillToscaOperationInputs(OperationDataDefinition operation, Map<String, DataTypeDefinition> dataTypes,
582 ToscaLifecycleOperationDefinition toscaOperation) {
583 if (Objects.isNull(operation.getInputs()) || operation.getInputs().isEmpty()) {
584 toscaOperation.setInputs(null);
587 Map<String, ToscaProperty> toscaInputs = new HashMap<>();
588 for (OperationInputDefinition input : operation.getInputs().getListToscaDataDefinition()) {
589 ToscaProperty toscaInput = new ToscaProperty();
590 toscaInput.setDescription(input.getDescription());
591 toscaInput.setType(input.getType());
592 toscaInput.setRequired(input.isRequired());
593 toscaInput.setDefaultp(propertyConvertor.convertToToscaObject(input, getInputValue(input), dataTypes, false));
594 toscaInputs.put(input.getName(), toscaInput);
596 toscaOperation.setInputs(toscaInputs);