/* * Copyright © 2016-2018 European Support Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.openecomp.sdc.be.tosca.utils; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import org.apache.commons.collections.MapUtils; import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.Product; import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.Service; import org.openecomp.sdc.be.tosca.model.ToscaInterfaceDefinition; import org.openecomp.sdc.be.tosca.model.ToscaInterfaceNodeType; import org.openecomp.sdc.be.tosca.model.ToscaLifecycleOperationDefinition; import org.openecomp.sdc.be.tosca.model.ToscaNodeType; import org.openecomp.sdc.be.tosca.model.ToscaProperty; /** * @author KATYR * @since March 20, 2018 */ public class InterfacesOperationsToscaUtil { private static final String DERIVED_FROM_STANDARD_INTERFACE = "tosca.interfaces.node.lifecycle.Standard"; private static final String OPERATIONS_KEY = "operations"; private static final String DEFAULT = "default"; private static final String _DEFAULT = "_default"; private static final String DOT = "."; private static final String DEFAULT_INPUT_TYPE = "string"; private static final String SELF = "SELF"; private static final String GET_PROPERTY = "get_property"; public static final String DEFAULTP = "defaultp"; /** * Creates the interface_types element * * @param component to work on * @return the added element */ public static Map addInterfaceTypeElement(Component component) { Map toscaInterfaceTypes = new HashMap<>(); if ((component instanceof Service) || (component instanceof Product)) { return null; } final Map interfaces = ((Resource) component).getInterfaces(); if ( MapUtils.isEmpty(interfaces)) { return null; } for (InterfaceDefinition interfaceDefinition : interfaces.values()) { ToscaInterfaceNodeType toscaInterfaceType = new ToscaInterfaceNodeType(); toscaInterfaceType.setDerived_from(DERIVED_FROM_STANDARD_INTERFACE); final Map operations = interfaceDefinition.getOperations(); Map toscaOperations = new HashMap<>(); for (String operationId : operations.keySet()) { toscaOperations.put(operations.get(operationId).getName(), null); //currently not initializing any of the operations' fields as it is not needed } toscaInterfaceType.setOperations(toscaOperations); Map interfacesAsMap = getObjectAsMap(toscaInterfaceType); Map operationsMap = (Map) interfacesAsMap.remove(OPERATIONS_KEY); interfacesAsMap.putAll(operationsMap); toscaInterfaceTypes.put(interfaceDefinition.getToscaResourceName(), interfacesAsMap); } return toscaInterfaceTypes; } /** * Adds the 'interfaces' element to the node type provided * * @param component to work on * @param nodeType to which the interfaces element will be added */ public static void addInterfaceDefinitionElement(Component component, ToscaNodeType nodeType) { Map toscaInterfaceDefinitions = new HashMap<>(); if ((component instanceof Service) || (component instanceof Product)) { return; } final Map interfaces = ((Resource) component).getInterfaces(); if ( MapUtils.isEmpty(interfaces)) { return; } for (InterfaceDefinition interfaceDefinition : interfaces.values()) { ToscaInterfaceDefinition toscaInterfaceDefinition = new ToscaInterfaceDefinition(); final String toscaResourceName = interfaceDefinition.getToscaResourceName(); toscaInterfaceDefinition.setType(toscaResourceName); final Map operations = interfaceDefinition.getOperations(); Map toscaOperations = new HashMap<>(); String operationArtifactPath; for (Map.Entry operationEntry : operations.entrySet()) { ToscaLifecycleOperationDefinition toscaOperation = new ToscaLifecycleOperationDefinition(); if (isArtifactPresent(operationEntry)) { operationArtifactPath = OperationArtifactUtil .createOperationArtifactPath(component.getNormalizedName(), interfaceDefinition.getToscaResourceName(), operationEntry.getValue()); toscaOperation.setImplementation(operationArtifactPath); } toscaOperation.setDescription(operationEntry.getValue().getDescription()); fillToscaOperationInputs(operationEntry.getValue(), toscaOperation); toscaOperations.put(operationEntry.getValue().getName(), toscaOperation); } toscaInterfaceDefinition.setOperations(toscaOperations); Map interfaceDefAsMap = getObjectAsMap(toscaInterfaceDefinition); Map operationsMap = (Map) interfaceDefAsMap.remove(OPERATIONS_KEY); handleDefaults(operationsMap); interfaceDefAsMap.putAll(operationsMap); toscaInterfaceDefinitions.put(getLastPartOfName(toscaResourceName), interfaceDefAsMap); } nodeType.setInterfaces(toscaInterfaceDefinitions); } /*** * workaround for : currently "defaultp" is not being converted to "default" by the relevant code in ToscaExportHandler * so, any string Map key named "defaultp" will have its named changed to "default" * @param operationsMap the map to update */ private static void handleDefaults(Map operationsMap) { for (String key : operationsMap.keySet()) { Object value = operationsMap.get(key); if (value instanceof Map) { handleDefaults((Map) value); } if (key.equals(DEFAULTP)) { Object removed = operationsMap.remove(key); operationsMap.put(DEFAULT, removed); } } } private static String getLastPartOfName(String toscaResourceName) { return toscaResourceName.substring(toscaResourceName.lastIndexOf(DOT) + 1); } private static boolean isArtifactPresent(Map.Entry operationEntry) { final boolean isImplementationPresent = !Objects.isNull(operationEntry.getValue().getImplementation()); if (isImplementationPresent) { return !Objects.isNull(operationEntry.getValue().getImplementation().getArtifactName()); } return false; } private static void fillToscaOperationInputs(OperationDataDefinition operation, ToscaLifecycleOperationDefinition toscaOperation) { if (Objects.isNull(operation.getInputs())) { return; } Map toscaInputs = new HashMap<>(); for (OperationInputDefinition input : operation.getInputs().getListToscaDataDefinition()) { ToscaProperty toscaInput = new ToscaProperty(); toscaInput.setDescription(input.getDescription()); toscaInput.setType(DEFAULT_INPUT_TYPE); toscaInput.setDefaultp(createDefaultValue(getLastPartOfName(input.getInputId()))); toscaInputs.put(input.getName(), toscaInput); } toscaOperation.setInputs(toscaInputs); } private static Map> createDefaultValue(String propertyName) { Map> getPropertyMap = new HashMap<>(); List values = new ArrayList<>(); values.add(SELF); values.add(propertyName); getPropertyMap.put(GET_PROPERTY, values); return getPropertyMap; } private static Map getObjectAsMap(Object obj) { Map objectAsMap = obj instanceof Map ? (Map) obj : new ObjectMapper().convertValue(obj, Map.class); if (objectAsMap.containsKey(DEFAULT)) { Object defaultValue = objectAsMap.get(DEFAULT); objectAsMap.remove(DEFAULT); objectAsMap.put(_DEFAULT, defaultValue); } return objectAsMap; } }