<commit_before>package com.oneops.transistor.service;

import com.oneops.cms.cm.domain.CmsCI;
import com.oneops.cms.cm.domain.CmsCIAttribute;
import com.oneops.cms.cm.domain.CmsCIRelation;
import com.oneops.cms.cm.domain.CmsCIRelationAttribute;
import com.oneops.cms.cm.service.CmsCmProcessor;
import com.oneops.cms.dj.domain.CmsRelease;
import com.oneops.cms.dj.domain.CmsRfcCI;
import com.oneops.cms.dj.domain.CmsRfcRelation;
import com.oneops.cms.dj.service.CmsCmRfcMrgProcessor;
import com.oneops.cms.dj.service.CmsRfcProcessor;
import com.oneops.cms.exceptions.DJException;
import com.oneops.cms.util.CmsConstants;
import com.oneops.transistor.exceptions.DesignExportException;
import com.oneops.transistor.export.domain.*;
import org.apache.log4j.Logger;

import java.util.*;
import java.util.stream.Collectors;

public class EnvironmentExportProcessor {
    private static final String USER_EXPORT = "export";
    private static Logger logger = Logger.getLogger(EnvironmentExportProcessor.class);
    private CmsCmProcessor cmProcessor;
    private CmsCmRfcMrgProcessor cmRfcMrgProcessor;
    private CmsRfcProcessor rfcProcessor;
    private TransUtil trUtil;
    private static final ExportFlavor FLAVOR = ExportFlavor.MANIFEST;
    private static final String BAD_ENV_ID_ERROR_MSG = "Environment does not exists with id=";
    private static final String OPEN_RELEASE_ERROR_MSG = "Design have open release. Please commit/discard before import.";
    private static final String CANT_FIND_PLATFORM_BY_NAME_ERROR_MSG = "Can not find platform with name: $toPlaform, used in links of platform $fromPlatform";
    private static final String CANT_FIND_COMPONENT_BY_NAME_ERROR_MSG = "Can not find component with name: $toComponent, used in depends of component $fromComponent";
    private static final String IMPORT_ERROR_PLAT_COMP = "Platform/Component - ";
    private static final String IMPORT_ERROR_PLAT_COMP_ATTACH = "Platform/Component/Attachment/Monitor - ";

    private static final String ACCOUNT_CLOUD_CLASS = "account.Cloud";
    private static final String DESIGN_MONITOR_CLASS = "catalog.Monitor";

    private static final String OWNER_MANIFEST = "manifest";
    private static final String ATTR_SECURE = "secure";
    private static final String ATTR_VALUE = "value";
    private static final String ATTR_ENC_VALUE = "encrypted_value";


    public void setRfcProcessor(CmsRfcProcessor rfcProcessor) {
        this.rfcProcessor = rfcProcessor;
    }

    public void setTrUtil(TransUtil trUtil) {
        this.trUtil = trUtil;
    }


    public void setCmRfcMrgProcessor(CmsCmRfcMrgProcessor cmRfcMrgProcessor) {
        this.cmRfcMrgProcessor = cmRfcMrgProcessor;
    }


    public void setCmProcessor(CmsCmProcessor cmProcessor) {
        this.cmProcessor = cmProcessor;
    }


    private DesignExportSimple exportDesign(long ciId, Long[] platformIds) {
        CmsCI ci = cmProcessor.getCiById(ciId);
        if (ci == null) {
            throw new DesignExportException(DesignExportException.CMS_NO_CI_WITH_GIVEN_ID_ERROR, BAD_ENV_ID_ERROR_MSG + ciId);
        }
        //export platforms
        DesignExportSimple des = new DesignExportSimple();

        List<CmsCIRelation> composedOfs;
        if (platformIds == null || platformIds.length == 0) {
            //get the global vars
            List<CmsCIRelation> globalVarRels = cmProcessor.getToCIRelations(ciId, FLAVOR.getGlobalVarRelation(), FLAVOR.getGlobalVarClass());
            for (CmsCIRelation gvRel : globalVarRels) {
                des.addVariable(gvRel.getFromCi().getCiName(), checkVar4Export(gvRel.getFromCi(), false));
            }
            composedOfs = cmProcessor.getFromCIRelations(ciId, FLAVOR.getComposedOfRelation(), FLAVOR.getPlatformClass());
        } else {
            composedOfs = cmProcessor.getFromCIRelationsByToCiIds(ciId, FLAVOR.getComposedOfRelation(), null, Arrays.asList(platformIds));
        }

        for (CmsCIRelation composedOf : composedOfs) {
            CmsCI platform = composedOf.getToCi();

            //export platform ci
            PlatformExport pe = stripAndSimplify(PlatformExport.class, platform, FLAVOR.getOwner());


            //local vars
            List<CmsCIRelation> localVarRels = cmProcessor.getToCIRelations(platform.getCiId(), FLAVOR.getLocalVarRelation(), FLAVOR.getLocalVarClass());

            for (CmsCIRelation lvRel : localVarRels) {
                pe.addVariable(lvRel.getFromCi().getCiName(), checkVar4Export(lvRel.getFromCi(), true));
            }

            //components
            addComponentsToPlatformExport(platform, pe);


            addConsumesRelation(platform, pe);
            des.addPlatformExport(pe);
        }
        return des;
    }


    private static String checkVar4Export(CmsCI var, boolean checkLock) {
        if ("true".equals(var.getAttribute(ATTR_SECURE).getDjValue())) {
            if (checkLock && !OWNER_MANIFEST.equals(var.getAttribute(ATTR_ENC_VALUE).getOwner())) {
                return null;
            }
            return RfcUtil.DUMMY_ENCRYPTED_EXP_VALUE;
        } else {
            if (checkLock && !OWNER_MANIFEST.equals(var.getAttribute(ATTR_VALUE).getOwner())) {
                return null;
            }
            return var.getAttribute(ATTR_VALUE).getDjValue();
        }
    }

    private void addConsumesRelation(CmsCI platform, PlatformExport pe) {
        List<CmsCIRelation> requiresRels = cmProcessor.getFromCIRelations(platform.getCiId(), FLAVOR.getConsumesRelation(), null);
        for (CmsCIRelation requires : requiresRels) {
            pe.addConsume(stripAndSimplify(ExportRelation.class, requires));
        }
    }


    private void addComponentsToPlatformExport(CmsCI platform, PlatformExport pe) {
        List<CmsCIRelation> requiresRels = cmProcessor.getFromCIRelations(platform.getCiId(), FLAVOR.getRequiresRelation(), null);
        for (CmsCIRelation requires : requiresRels) {
            CmsCI component = requires.getToCi();

            boolean isOptional = requires.getAttribute("constraint").getDjValue().startsWith("0.");    //always export optionals components or with attachments
            String template = requires.getAttribute("template").getDjValue();


            List<String> relationNames = Arrays.asList(FLAVOR.getEscortedRelation(), FLAVOR.getWatchedByRelation(), FLAVOR.getDependsOnRelation());

            Map<String, List<CmsCIRelation>> relationsMap = cmProcessor.getFromCIRelationsByMultiRelationNames(component.getCiId(),
                    relationNames, null);
            List<CmsCIRelation> attachmentRels = relationsMap.get(FLAVOR.getEscortedRelation());
            List<CmsCIRelation> watchedByRels = relationsMap.get(FLAVOR.getWatchedByRelation());
            List<CmsCIRelation> dependsOnRels = relationsMap.get(FLAVOR.getDependsOnRelation());
            if (attachmentRels == null)
                attachmentRels = Collections.emptyList();
            if (watchedByRels == null)
                watchedByRels = Collections.emptyList();
            if (dependsOnRels == null) {
                dependsOnRels = Collections.emptyList();
            }

            List<CmsCIRelation> flexes = dependsOnRels.stream().filter(relation -> relation.getAttribute("flex") != null && "true".equalsIgnoreCase(relation.getAttribute("flex").getDjValue())).collect(Collectors.toList());

            ComponentExport eCi = stripAndSimplify(ComponentExport.class, component, FLAVOR.getOwner(), false, ((attachmentRels.size() + watchedByRels.size() + flexes.size()) > 0 || isOptional));
            if (eCi != null) {
                eCi.setTemplate(template);
                for (CmsCIRelation attachmentRel : attachmentRels) {
                    eCi.addAttachment(stripAndSimplify(ExportCi.class, attachmentRel.getToCi(), FLAVOR.getOwner(), true, false));
                }
                for (CmsCIRelation watchedByRel : watchedByRels) {
                    ExportCi monitorCi = stripAndSimplify(ExportCi.class, watchedByRel.getToCi(), FLAVOR.getOwner(), isCustomMonitor(watchedByRel), false);
                    if (monitorCi != null) {
                        eCi.addMonitor(monitorCi);
                    }
                }
                for (CmsCIRelation scaling : flexes) {
                    eCi.addScaling(scaling.getToCi().getCiClassName(), scaling.getToCi().getCiName(), stripAndSimplify(ExportRelation.class, scaling));
                }
                if (isOptional || !isEmpty(eCi.getAttachments()) || !isEmpty(eCi.getMonitors()) || !isEmpty(eCi.getScaling())) {
                    pe.addComponent(eCi);
                }
            }
        }
    }

    private static boolean isEmpty(Map scaling) {
        return scaling == null || scaling.isEmpty();
    }

    private static boolean isEmpty(List list) {
        return list == null || list.size() == 0;
    }
<commit_msg>optional and modified components import/export works now<commit_after>package com.oneops.transistor.service;

import com.oneops.cms.cm.domain.CmsCI;
import com.oneops.cms.cm.domain.CmsCIAttribute;
import com.oneops.cms.cm.domain.CmsCIRelation;
import com.oneops.cms.cm.domain.CmsCIRelationAttribute;
import com.oneops.cms.cm.service.CmsCmProcessor;
import com.oneops.cms.dj.domain.CmsRelease;
import com.oneops.cms.dj.domain.CmsRfcCI;
import com.oneops.cms.dj.domain.CmsRfcRelation;
import com.oneops.cms.dj.service.CmsCmRfcMrgProcessor;
import com.oneops.cms.dj.service.CmsRfcProcessor;
import com.oneops.cms.exceptions.DJException;
import com.oneops.cms.util.CmsConstants;
import com.oneops.transistor.exceptions.DesignExportException;
import com.oneops.transistor.export.domain.*;
import org.apache.log4j.Logger;

import java.util.*;
import java.util.stream.Collectors;

public class EnvironmentExportProcessor {
    private static final String USER_EXPORT = "export";
    private static Logger logger = Logger.getLogger(EnvironmentExportProcessor.class);
    private CmsCmProcessor cmProcessor;
    private CmsCmRfcMrgProcessor cmRfcMrgProcessor;
    private CmsRfcProcessor rfcProcessor;
    private TransUtil trUtil;
    private static final ExportFlavor FLAVOR = ExportFlavor.MANIFEST;
    private static final String BAD_ENV_ID_ERROR_MSG = "Environment does not exists with id=";
    private static final String OPEN_RELEASE_ERROR_MSG = "Design have open release. Please commit/discard before import.";
    private static final String CANT_FIND_PLATFORM_BY_NAME_ERROR_MSG = "Can not find platform with name: $toPlaform, used in links of platform $fromPlatform";
    private static final String CANT_FIND_COMPONENT_BY_NAME_ERROR_MSG = "Can not find component with name: $toComponent, used in depends of component $fromComponent";
    private static final String IMPORT_ERROR_PLAT_COMP = "Platform/Component - ";
    private static final String IMPORT_ERROR_PLAT_COMP_ATTACH = "Platform/Component/Attachment/Monitor - ";

    private static final String ACCOUNT_CLOUD_CLASS = "account.Cloud";
    private static final String DESIGN_MONITOR_CLASS = "catalog.Monitor";

    private static final String OWNER_MANIFEST = "manifest";
    private static final String ATTR_SECURE = "secure";
    private static final String ATTR_VALUE = "value";
    private static final String ATTR_ENC_VALUE = "encrypted_value";


    public void setRfcProcessor(CmsRfcProcessor rfcProcessor) {
        this.rfcProcessor = rfcProcessor;
    }

    public void setTrUtil(TransUtil trUtil) {
        this.trUtil = trUtil;
    }


    public void setCmRfcMrgProcessor(CmsCmRfcMrgProcessor cmRfcMrgProcessor) {
        this.cmRfcMrgProcessor = cmRfcMrgProcessor;
    }


    public void setCmProcessor(CmsCmProcessor cmProcessor) {
        this.cmProcessor = cmProcessor;
    }


    private DesignExportSimple exportDesign(long ciId, Long[] platformIds) {
        CmsCI ci = cmProcessor.getCiById(ciId);
        if (ci == null) {
            throw new DesignExportException(DesignExportException.CMS_NO_CI_WITH_GIVEN_ID_ERROR, BAD_ENV_ID_ERROR_MSG + ciId);
        }
        //export platforms
        DesignExportSimple des = new DesignExportSimple();

        List<CmsCIRelation> composedOfs;
        if (platformIds == null || platformIds.length == 0) {
            //get the global vars
            List<CmsCIRelation> globalVarRels = cmProcessor.getToCIRelations(ciId, FLAVOR.getGlobalVarRelation(), FLAVOR.getGlobalVarClass());
            for (CmsCIRelation gvRel : globalVarRels) {
                des.addVariable(gvRel.getFromCi().getCiName(), checkVar4Export(gvRel.getFromCi(), false));
            }
            composedOfs = cmProcessor.getFromCIRelations(ciId, FLAVOR.getComposedOfRelation(), FLAVOR.getPlatformClass());
        } else {
            composedOfs = cmProcessor.getFromCIRelationsByToCiIds(ciId, FLAVOR.getComposedOfRelation(), null, Arrays.asList(platformIds));
        }

        for (CmsCIRelation composedOf : composedOfs) {
            CmsCI platform = composedOf.getToCi();

            //export platform ci
            PlatformExport pe = stripAndSimplify(PlatformExport.class, platform, FLAVOR.getOwner());


            //local vars
            List<CmsCIRelation> localVarRels = cmProcessor.getToCIRelations(platform.getCiId(), FLAVOR.getLocalVarRelation(), FLAVOR.getLocalVarClass());

            for (CmsCIRelation lvRel : localVarRels) {
                pe.addVariable(lvRel.getFromCi().getCiName(), checkVar4Export(lvRel.getFromCi(), true));
            }

            //components
            addComponentsToPlatformExport(platform, pe);


            addConsumesRelation(platform, pe);
            des.addPlatformExport(pe);
        }
        return des;
    }


    private static String checkVar4Export(CmsCI var, boolean checkLock) {
        if ("true".equals(var.getAttribute(ATTR_SECURE).getDjValue())) {
            if (checkLock && !OWNER_MANIFEST.equals(var.getAttribute(ATTR_ENC_VALUE).getOwner())) {
                return null;
            }
            return RfcUtil.DUMMY_ENCRYPTED_EXP_VALUE;
        } else {
            if (checkLock && !OWNER_MANIFEST.equals(var.getAttribute(ATTR_VALUE).getOwner())) {
                return null;
            }
            return var.getAttribute(ATTR_VALUE).getDjValue();
        }
    }

    private void addConsumesRelation(CmsCI platform, PlatformExport pe) {
        List<CmsCIRelation> requiresRels = cmProcessor.getFromCIRelations(platform.getCiId(), FLAVOR.getConsumesRelation(), null);
        for (CmsCIRelation requires : requiresRels) {
            pe.addConsume(stripAndSimplify(ExportRelation.class, requires));
        }
    }


    private void addComponentsToPlatformExport(CmsCI platform, PlatformExport pe) {
        List<CmsCIRelation> requiresRels = cmProcessor.getFromCIRelations(platform.getCiId(), FLAVOR.getRequiresRelation(), null);
        for (CmsCIRelation requires : requiresRels) {
            CmsCI component = requires.getToCi();

            boolean isOptional = requires.getAttribute("constraint").getDjValue().startsWith("0.");    //always export optionals components or with attachments
            String template = requires.getAttribute("template").getDjValue();


            List<String> relationNames = Arrays.asList(FLAVOR.getEscortedRelation(), FLAVOR.getWatchedByRelation(), FLAVOR.getDependsOnRelation());

            Map<String, List<CmsCIRelation>> relationsMap = cmProcessor.getFromCIRelationsByMultiRelationNames(component.getCiId(),
                    relationNames, null);
            List<CmsCIRelation> attachmentRels = relationsMap.get(FLAVOR.getEscortedRelation());
            List<CmsCIRelation> watchedByRels = relationsMap.get(FLAVOR.getWatchedByRelation());
            List<CmsCIRelation> dependsOnRels = relationsMap.get(FLAVOR.getDependsOnRelation());
            if (attachmentRels == null)
                attachmentRels = Collections.emptyList();
            if (watchedByRels == null)
                watchedByRels = Collections.emptyList();
            if (dependsOnRels == null) {
                dependsOnRels = Collections.emptyList();
            }

            List<CmsCIRelation> flexes = dependsOnRels.stream().filter(relation -> relation.getAttribute("flex") != null && "true".equalsIgnoreCase(relation.getAttribute("flex").getDjValue())).collect(Collectors.toList());

            ComponentExport eCi = stripAndSimplify(ComponentExport.class, component, FLAVOR.getOwner(), false, ((attachmentRels.size() + watchedByRels.size() + flexes.size()) > 0 || isOptional));
            if (eCi != null) {
                eCi.setTemplate(template);
                for (CmsCIRelation attachmentRel : attachmentRels) {
                    eCi.addAttachment(stripAndSimplify(ExportCi.class, attachmentRel.getToCi(), FLAVOR.getOwner(), true, false));
                }
                for (CmsCIRelation watchedByRel : watchedByRels) {
                    ExportCi monitorCi = stripAndSimplify(ExportCi.class, watchedByRel.getToCi(), FLAVOR.getOwner(), isCustomMonitor(watchedByRel), false);
                    if (monitorCi != null) {
                        eCi.addMonitor(monitorCi);
                    }
                }
                for (CmsCIRelation scaling : flexes) {
                    eCi.addScaling(scaling.getToCi().getCiClassName(), scaling.getToCi().getCiName(), stripAndSimplify(ExportRelation.class, scaling));
                }
                if (isOptional || !isEmpty(eCi.getAttachments()) || !isEmpty(eCi.getMonitors()) || !isEmpty(eCi.getScaling()) || (eCi.getAttributes()!=null && !eCi.getAttributes().isEmpty())) {
                    pe.addComponent(eCi);
                }
            }
        }
    }

    private static boolean isEmpty(Map scaling) {
        return scaling == null || scaling.isEmpty();
    }

    private static boolean isEmpty(List list) {
        return list == null || list.size() == 0;
    }

{'fraction_non_alphanumeric': 0.0987026059724863, 'fraction_numerical': 0.0008947545017335869, 'mean_word_length': 3.1347976878612718, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '378207', 'n_tokens_mistral': 5441, 'n_tokens_neox': 5200, 'n_words': 964}