org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil.java

Source

/*-
 * ============LICENSE_START=======================================================
 * SDC
 * ================================================================================
 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
 * ================================================================================
 * 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.
 * ============LICENSE_END=========================================================
 */

package org.openecomp.sdc.translator.services.heattotosca;

import org.apache.commons.collections4.CollectionUtils;
import org.openecomp.core.utilities.yaml.YamlUtil;
import org.openecomp.sdc.common.errors.CoreException;
import org.openecomp.sdc.heat.datatypes.HeatBoolean;
import org.openecomp.sdc.heat.datatypes.manifest.FileData;
import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
import org.openecomp.sdc.heat.datatypes.model.Resource;
import org.openecomp.sdc.heat.services.HeatConstants;
import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
import org.openecomp.sdc.tosca.services.ToscaUtil;
import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
import org.openecomp.sdc.translator.datatypes.heattotosca.ResourceReferenceType;
import org.openecomp.sdc.translator.datatypes.heattotosca.to.FileDataCollection;
import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
import org.openecomp.sdc.translator.services.heattotosca.errors.ResourceNotFoundInHeatFileErrorBuilder;
import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaFunctionConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

public class HeatToToscaUtil {

    protected static Logger logger = LoggerFactory.getLogger(HeatToToscaUtil.class);

    /**
     * Build list of files to search optional.
     *
     * @param heatFileName  the heat file name
     * @param filesDataList the files data list
     * @param types         the types
     * @return the optional
     */
    public static Optional<List<FileData>> buildListOfFilesToSearch(String heatFileName,
            List<FileData> filesDataList, FileData.Type... types) {
        List<FileData> list = new ArrayList<>(filesDataList);
        Optional<FileData> resourceFileData = HeatToToscaUtil.getFileData(heatFileName, filesDataList);
        if (resourceFileData.isPresent() && Objects.nonNull(resourceFileData.get().getData())) {
            list.addAll(resourceFileData.get().getData());
        }
        return Optional.ofNullable(HeatToToscaUtil.getFilteredListOfFileDataByTypes(list, types));
    }

    public static List<FileData> getFilteredListOfFileDataByTypes(List<FileData> filesToSearch,
            FileData.Type... types) {
        return filesToSearch.stream().filter(FileData.buildFileDataPredicateByType(types))
                .collect(Collectors.toList());
    }

    /**
     * Gets file data.
     *
     * @param heatFileName the heat file name
     * @param fileDataList the file data list
     * @return the file data
     */
    public static Optional<FileData> getFileData(String heatFileName, Collection<FileData> fileDataList) {
        for (FileData file : fileDataList) {
            if (file.getFile().equals(heatFileName)) {
                return Optional.of(file);
            }
        }
        return Optional.empty();
    }

    static FileDataCollection getFileCollectionsByFilter(List<FileData> fileDataList, Set<FileData.Type> typeFilter,
            TranslationContext translationContext) {
        FileDataCollection fileDataCollection = new FileDataCollection();
        Map<String, FileData> filteredFiles = filterFileDataListByType(fileDataList, typeFilter);
        Set<String> referenced = new HashSet<>();
        List<String> filenames = extractFilenamesFromFileDataList(filteredFiles.values());

        for (FileData fileData : filteredFiles.values()) {
            String fileName = fileData.getFile();

            if (FileData.isHeatFile(fileData.getType())) {
                if (fileData.getBase() != null && fileData.getBase().equals(true)) {
                    fileDataCollection.addBaseFiles(fileData);
                }
                HeatOrchestrationTemplate heatOrchestrationTemplate = new YamlUtil()
                        .yamlToObject(translationContext.getFileContent(fileName), HeatOrchestrationTemplate.class);
                for (Resource resource : heatOrchestrationTemplate.getResources().values()) {
                    if (filenames.contains(resource.getType())) {
                        handleNestedFile(translationContext, fileDataCollection, filteredFiles, referenced,
                                resource.getType());
                    } else if (resource.getType()
                            .equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
                        Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
                        Object innerTypeDef = ((Map) resourceDef).get("type");
                        if (innerTypeDef instanceof String) {
                            String internalResourceType = (String) innerTypeDef;
                            if (filenames.contains(internalResourceType)) {
                                handleNestedFile(translationContext, fileDataCollection, filteredFiles, referenced,
                                        internalResourceType);
                            }
                        }
                    }
                }

            } else {
                fileDataCollection.addArtifactFiles(fileData);
                filteredFiles.remove(fileData.getFile());
            }
        }

        referenced.forEach(filteredFiles::remove);
        if (!CollectionUtils.isEmpty(fileDataCollection.getBaseFile())) {
            for (FileData fileData : fileDataCollection.getBaseFile()) {
                filteredFiles.remove(fileData.getFile());
            }
        }
        fileDataCollection.setAddOnFiles(filteredFiles.values());
        return fileDataCollection;
    }

    private static void handleNestedFile(TranslationContext translationContext,
            FileDataCollection fileDataCollection, Map<String, FileData> filteredFiles, Set<String> referenced,
            String nestedFileName) {
        referenced.add(nestedFileName);
        fileDataCollection.addNestedFiles(filteredFiles.get(nestedFileName));
        translationContext.getNestedHeatsFiles().add(nestedFileName);
    }

    private static Map<String, FileData> filterFileDataListByType(List<FileData> fileDataList,
            Set<FileData.Type> typesToGet) {
        Map<String, FileData> filtered = new HashMap<>();
        fileDataList.stream().filter(file -> typesToGet.contains(file.getType()))
                .forEach(file -> filtered.put(file.getFile(), file));
        return filtered;
    }

    private static List<String> extractFilenamesFromFileDataList(Collection<FileData> fileDataList) {
        return fileDataList.stream().map(FileData::getFile).collect(Collectors.toList());
    }

    /**
     * Extract attached resource id optional.
     *
     * @param translateTo  the translate to
     * @param propertyName the property name
     * @return the optional
     */
    public static Optional<AttachedResourceId> extractAttachedResourceId(TranslateTo translateTo,
            String propertyName) {
        Object propertyValue = translateTo.getResource().getProperties().get(propertyName);
        if (propertyValue == null) {
            return Optional.empty();
        }
        return extractAttachedResourceId(translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(),
                translateTo.getContext(), propertyValue);
    }

    /**
     * Extract attached resource id optional.
     *
     * @param heatFileName              the heat file name
     * @param heatOrchestrationTemplate the heat orchestration template
     * @param context                   the context
     * @param propertyValue             the property value
     * @return the optional
     */
    public static Optional<AttachedResourceId> extractAttachedResourceId(String heatFileName,
            HeatOrchestrationTemplate heatOrchestrationTemplate, TranslationContext context, Object propertyValue) {

        Object entity;
        Object translatedId;

        if (Objects.isNull(propertyValue)) {
            return Optional.empty();
        }

        ResourceReferenceType referenceType = ResourceReferenceType.OTHER;
        if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
            Map<String, Object> propMap = (Map) propertyValue;
            Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
            entity = entry.getValue();
            String key = entry.getKey();
            switch (key) {
            case "get_resource":
                referenceType = ResourceReferenceType.GET_RESOURCE;
                break;
            case "get_param":
                referenceType = ResourceReferenceType.GET_PARAM;
                break;
            case "get_attr":
                referenceType = ResourceReferenceType.GET_ATTR;
                break;
            default:
            }
            translatedId = TranslatorHeatToToscaFunctionConverter.getToscaFunction(entry.getKey(), entry.getValue(),
                    heatFileName, heatOrchestrationTemplate, null, context);
            if (translatedId instanceof String
                    && !TranslatorHeatToToscaFunctionConverter.isResourceSupported((String) translatedId)) {
                translatedId = null;
            }

        } else {
            translatedId = propertyValue;
            entity = propertyValue;
        }

        return Optional.of(new AttachedResourceId(translatedId, entity, referenceType));
    }

    /**
     * Gets contrail attached heat resource id.
     *
     * @param attachedResource the attached resource
     * @return the contrail attached heat resource id
     */
    public static Optional<String> getContrailAttachedHeatResourceId(AttachedResourceId attachedResource) {
        if (attachedResource == null) {
            return Optional.empty();
        }

        if (attachedResource.isGetResource()) {
            return Optional.of((String) attachedResource.getEntityId());
        }
        if (attachedResource.isGetAttr() && (attachedResource.getEntityId() instanceof List)
                && ((List) attachedResource.getEntityId()).size() > 1
                && ((List) attachedResource.getEntityId()).get(1).equals("fq_name")) {
            return Optional.of((String) ((List) attachedResource.getEntityId()).get(0));
        }

        return Optional.empty();
    }

    /**
     * Extract property optional.
     *
     * @param propertyValue the property value
     * @return the optional
     */
    public static Optional<AttachedResourceId> extractProperty(Object propertyValue) {

        Object entity;
        if (Objects.isNull(propertyValue)) {
            return Optional.empty();
        }

        ResourceReferenceType referenceType = ResourceReferenceType.OTHER;
        if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
            Map<String, Object> propMap = (Map) propertyValue;
            Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
            entity = entry.getValue();
            String key = entry.getKey();
            switch (key) {
            case "get_resource":
                referenceType = ResourceReferenceType.GET_RESOURCE;
                break;
            case "get_param":
                referenceType = ResourceReferenceType.GET_PARAM;
                break;
            case "get_attr":
                referenceType = ResourceReferenceType.GET_ATTR;
                break;
            default:
            }

        } else {
            entity = propertyValue;
        }

        return Optional.of(new AttachedResourceId(null, entity, referenceType));
    }

    /**
     * Map boolean.
     *
     * @param nodeTemplate the node template
     * @param propertyKey  the property key
     */
    public static void mapBoolean(NodeTemplate nodeTemplate, String propertyKey) {
        Object value = nodeTemplate.getProperties().get(propertyKey);
        if (value != null && !(value instanceof Map)) {
            nodeTemplate.getProperties().put(propertyKey, HeatBoolean.eval(value));
        }
    }

    /**
     * Map boolean list.
     *
     * @param nodeTemplate    the node template
     * @param propertyListKey the property list key
     */
    public static void mapBooleanList(NodeTemplate nodeTemplate, String propertyListKey) {
        Object listValue = nodeTemplate.getProperties().get(propertyListKey);
        if (listValue instanceof List) {
            List booleanList = ((List) listValue);
            for (int i = 0; i < booleanList.size(); i++) {
                Object value = booleanList.get(i);
                if (value != null && !(value instanceof Map)) {
                    booleanList.set(i, HeatBoolean.eval(value));
                }
            }
        }
    }

    public static boolean isYmlFileType(String filename) {
        return (filename.indexOf("yaml") > 0 || filename.indexOf("yml") > 0);
    }

    /**
     * Is nested resource boolean.
     *
     * @param resource the resource
     * @return the boolean
     */
    public static boolean isNestedResource(Resource resource) {
        String resourceType = resource.getType();

        if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
            Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
            String internalResourceType = (String) ((Map) resourceDef).get("type");
            if (isYamlFile(internalResourceType)) {
                return true;
            }
        } else if (isYamlFile(resourceType)) {
            return true;
        }
        return false;
    }

    /**
     * Gets nested file.
     *
     * @param resource the resource
     * @return the nested file
     */
    public static Optional<String> getNestedFile(Resource resource) {
        if (!isNestedResource(resource)) {
            return Optional.empty();
        }
        String resourceType = resource.getType();
        if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
            Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
            String internalResourceType = (String) ((Map) resourceDef).get("type");
            return Optional.of(internalResourceType);
        } else {
            return Optional.of(resourceType);
        }
    }

    private static boolean isYamlFile(String fileName) {
        return fileName.endsWith(".yaml") || fileName.endsWith(".yml");
    }

    /**
     * Gets resource.
     *
     * @param heatOrchestrationTemplate the heat orchestration template
     * @param resourceId                the resource id
     * @param heatFileName              the heat file name
     * @return the resource
     */
    public static Resource getResource(HeatOrchestrationTemplate heatOrchestrationTemplate, String resourceId,
            String heatFileName) {
        Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
        if (resource == null) {
            throw new CoreException(new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
        }
        return resource;
    }

    public static boolean isHeatFileNested(TranslateTo translateTo, String heatFileName) {
        return translateTo.getContext().getNestedHeatsFiles().contains(heatFileName);
    }

    /**
     * Extract contrail get resource attached heat resource id string.
     *
     * @param propertyValue the property value
     * @return the string
     */
    public static String extractContrailGetResourceAttachedHeatResourceId(Object propertyValue) {
        if (propertyValue == null) {
            return null;
        }

        Object value;
        if (propertyValue instanceof Map) {
            if (((Map) propertyValue).containsKey("get_attr")) {
                value = ((Map) propertyValue).get("get_attr");
                if (value instanceof List) {
                    if (((List) value).size() == 2 && ((List) value).get(1).equals("fq_name")) {
                        if (((List) value).get(0) instanceof String) {
                            return (String) ((List) value).get(0);
                        } else {
                            logger.warn("invalid format of 'get_attr' function - " + propertyValue.toString());
                        }
                    }
                }
            } else if (((Map) propertyValue).containsKey("get_resource")) {
                value = ((Map) propertyValue).get("get_resource");
                if (value instanceof String) {
                    return (String) value;
                } else {
                    logger.warn("invalid format of 'get_resource' function - " + propertyValue.toString());
                }
            } else {
                Collection<Object> valCollection = ((Map) propertyValue).values();
                for (Object entryValue : valCollection) {
                    String ret = extractContrailGetResourceAttachedHeatResourceId(entryValue);
                    if (ret != null) {
                        return ret;
                    }

                }
            }
        } else if (propertyValue instanceof List) {
            for (Object prop : (List) propertyValue) {
                String ret = extractContrailGetResourceAttachedHeatResourceId(prop);
                if (ret != null) {
                    return ret;
                }
            }
        }
        return null;
    }

    /**
     * Gets tosca service model.
     *
     * @param translateTo the translate to
     * @return the tosca service model
     */
    public static ToscaServiceModel getToscaServiceModel(TranslateTo translateTo) {
        Map<String, ServiceTemplate> serviceTemplates = new HashMap<>(
                translateTo.getContext().getGlobalServiceTemplates());
        Collection<ServiceTemplate> tmpServiceTemplates = translateTo.getContext().getTranslatedServiceTemplates()
                .values();
        for (ServiceTemplate serviceTemplate : tmpServiceTemplates) {
            ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplate);
        }
        return new ToscaServiceModel(null, serviceTemplates,
                ToscaUtil.getServiceTemplateFileName(translateTo.getResource().getType()));
    }

    /**
     * Gets service template from context.
     *
     * @param serviceTemplateFileName the service template file name
     * @param context                 the context
     * @return the service template from context
     */
    public static Optional<ServiceTemplate> getServiceTemplateFromContext(String serviceTemplateFileName,
            TranslationContext context) {
        for (ServiceTemplate serviceTemplate : context.getTranslatedServiceTemplates().values()) {
            if (ToscaUtil.getServiceTemplateFileName(serviceTemplate).equals(serviceTemplateFileName)) {
                return Optional.of(serviceTemplate);
            }
        }

        return Optional.empty();
    }
}