All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.wildfly.glow.ScanResultsPrinter Maven / Gradle / Ivy

The newest version!
/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2023 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * 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.wildfly.glow;

import org.wildfly.glow.error.ErrorLevel;
import org.wildfly.glow.error.IdentifiedError;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.jboss.galleon.api.config.GalleonFeaturePackConfig;
import org.jboss.galleon.universe.FeaturePackLocation.FPID;
import org.wildfly.glow.ConfigurationResolver.ResolvedEnvs;

public class ScanResultsPrinter {

    private final GlowMessageWriter writer;
    private final ConfigurationResolver configResolver;

    public ScanResultsPrinter(GlowMessageWriter writer) {
        this(writer, null);
    }

    public ScanResultsPrinter(GlowMessageWriter writer, ConfigurationResolver configResolver) {
        this.writer = writer;
        this.configResolver = configResolver;
    }

    void print(ScanArguments arguments, ScanResults scanResults) throws Exception {
        if (arguments.isCompact()) {
            printCompact(arguments, scanResults);
        } else {
            detailed(arguments, scanResults);
        }
    }

    void printCompact(ScanArguments arguments, ScanResults scanResults) throws Exception {
        writer.info(getCompactInformation(arguments, scanResults));
    }

    String getCompactInformation(ScanArguments arguments, ScanResults scanResults) throws Exception {
        StringBuilder compactBuilder = new StringBuilder();
        if (!arguments.getExecutionProfiles().isEmpty()) {
            compactBuilder.append(new TreeSet<>(arguments.getExecutionProfiles()));
        }
        compactBuilder.append(new TreeSet<>(scanResults.getDiscoveredLayers())).append("==>");
        compactBuilder.append(scanResults.getBaseLayer());
        for (Layer l : new TreeSet<>(scanResults.getDecorators())) {
            compactBuilder.append(",").append(l.getName());
        }
        for (Layer l : new TreeSet<>(scanResults.getExcludedLayers())) {
            compactBuilder.append(",-").append(l.getName());
        }
        return compactBuilder.toString();
    }

    private void detailed(ScanArguments arguments, ScanResults scanResults) throws Exception {
        writer.info("context: " + arguments.getExecutionContext());
        StringBuilder profileBuilder = new StringBuilder();
        profileBuilder.append("enabled profile: ");
        if (!arguments.getExecutionProfiles().isEmpty()) {
            for (String p : arguments.getExecutionProfiles()) {
                profileBuilder.append(p);
            }
        } else {
            profileBuilder.append("none");
        }
        writer.info(profileBuilder);
        if(arguments.getConfigStability() != null) {
            writer.info("config stability: " + arguments.getConfigStability().toString());
        }
        if(arguments.getPackageStability() != null) {
            writer.info("package stability: " + arguments.getPackageStability().toString());
        }
        writer.info("galleon discovery");
        StringBuilder builder = new StringBuilder();
        builder.append("- feature-packs").append("\n");
        for (GalleonFeaturePackConfig fp : scanResults.getProvisioningConfig().getFeaturePackDeps()) {
            FPID fpid = scanResults.getFeaturePackVersions().get(fp.getLocation().getProducer());
            builder.append("   ").append(fpid == null ? fp.getLocation() : fpid).append("\n");
        }
        builder.append("- layers").append("\n");
        builder.append("   ").append(scanResults.getBaseLayer()).append("\n");
        for (Layer l : scanResults.getDecorators()) {
            builder.append("   ").append(l.getName() + (scanResults.getExcludedFeatures().containsKey(l) ? " [WARNING: contains content at a lower stability level]" : "")).append("\n");
        }
        if (!scanResults.getExcludedLayers().isEmpty()) {
            builder.append("- excluded-layers\n");
            for (Layer l : scanResults.getExcludedLayers()) {
                builder.append("   ").append(l.getName()).append("\n");
            }
        }
        writer.info(builder);
        if (arguments.isVerbose()) {
            StringBuilder rulesBuilder = new StringBuilder();
            rulesBuilder.append("\nlayers inclusion rules").append("\n");
            rulesBuilder.append("* ").append(scanResults.getBaseLayer()).append("\n");
            for (LayerMapping.RULE rule : scanResults.getBaseLayer().getMatchingRules().keySet()) {
                Set str = scanResults.getBaseLayer().getMatchingRules().get(rule);
                rulesBuilder.append("  - ").append(rule).append((str == null || str.isEmpty()) ? "" : ": " + str).append("\n");
            }
            for (Layer l : scanResults.getDecorators()) {
                rulesBuilder.append("* ").append(l.getName()).append("\n");
                for (LayerMapping.RULE rule : l.getMatchingRules().keySet()) {
                    Set str = l.getMatchingRules().get(rule);
                    rulesBuilder.append("  - ").append(rule).append((str == null || str.isEmpty()) ? "" : ": " + str).append("\n");
                }
            }
            writer.info(rulesBuilder.toString());
        }
        if (!scanResults.getEnabledAddOns().isEmpty()) {
            writer.info("enabled add-ons");
            StringBuilder addOnsBuilder = new StringBuilder();
            for (AddOn l : scanResults.getEnabledAddOns()) {
                addOnsBuilder.append("- ").append(l.getName()).append(l.getDescription() != null ? " : " + l.getDescription() : "").append("\n");
            }
            writer.info(addOnsBuilder);
        }
        if (!scanResults.getDisabledAddOns().isEmpty()) {
            writer.info("disabled add-ons");
            StringBuilder disabledBuilder = new StringBuilder();
            for (Map.Entry l : scanResults.getDisabledAddOns().entrySet()) {
                disabledBuilder.append("- ").append(l.getKey().getName()).append(": ").append(l.getValue()).append("\n");
            }
            writer.info(disabledBuilder);
        }
        List fixBuilders = new ArrayList<>();
        List errorBuilders = new ArrayList<>();
        List warnBuilders = new ArrayList<>();
        for (IdentifiedError error : scanResults.getErrorSession().getErrors()) {
            if (error.isFixed()) {
                StringBuilder fixBuilder = new StringBuilder();
                fixBuilder.append("* ").append(error.getDescription()).append(" is fixed\n");
                fixBuilder.append("  - ").append(error.getFixMessage()).append("\n");
                fixBuilders.add(fixBuilder);
            } else {
                StringBuilder errorBuilder = new StringBuilder();
                errorBuilder.append("* ").append(error.getDescription()).append("\n");
                if (!error.getPossibleAddons().isEmpty()) {
                    errorBuilder.append("  To correct this error, enable one of the following add-ons:\n");
                    for (AddOn addOn : error.getPossibleAddons()) {
                        String deployer = configResolver == null ? null : configResolver.getPossibleDeployer(addOn.getLayers());
                        errorBuilder.append("  - ").append(addOn.getName()).append((deployer == null ? "" : " (supported by "+deployer+" deployer)")).append("\n");
                    }
                }
                if (error.getErrorLevel() == ErrorLevel.ERROR) {
                    errorBuilders.add(errorBuilder);
                } else {
                    warnBuilders.add(errorBuilder);
                }
            }
        }

        if (!errorBuilders.isEmpty()) {
            writer.info("identified errors");
            for (StringBuilder errorBuilder : errorBuilders) {
                writer.error(errorBuilder);
            }
        }

        if (!warnBuilders.isEmpty()) {
            writer.info("possible issues");
            for (StringBuilder warnBuilder : warnBuilders) {
                writer.warn(warnBuilder);
            }
        }
        if (!fixBuilders.isEmpty()) {
            writer.info("identified fixes");
            for (StringBuilder fixBuilder : fixBuilders) {
                writer.info(fixBuilder);
            }
        }

        if (configResolver != null) {
            Set deployers = new TreeSet<>();
            for (Layer l : scanResults.getDiscoveredLayers()) {
                String deployer = configResolver.getPossibleDeployer(l);
                if (deployer != null) {
                    deployers.add(deployer);
                }
            }
            for (Layer l : scanResults.getMetadataOnlyLayers()) {
                String deployer = configResolver.getPossibleDeployer(l);
                if (deployer != null) {
                    deployers.add(deployer);
                }
            }
            if (!deployers.isEmpty()) {
                writer.info("deployers that would get automatically enabled when deploying to openshift");
                for (String deployer : deployers) {
                    writer.info("- " + deployer);
                }
                writer.info("");
            }
        }

        if (!scanResults.getSuggestions().getStronglySuggestedConfigurations().isEmpty()) {
            writer.warn("strongly suggested configuration at runtime");
            for(Map.Entry> entry : scanResults.getSuggestions().getStronglySuggestedConfigurations().entrySet()) {
                writer.warn(buildSuggestions(entry.getKey(), entry.getValue()));
            }
            writer.warn("");
        }

        if (!scanResults.getSuggestions().getBuildTimeRequiredConfigurations().isEmpty()) {
            writer.warn("configuration that must be set at provisioning time");
            for(Map.Entry> entry : scanResults.getSuggestions().getBuildTimeRequiredConfigurations().entrySet()) {
                writer.warn(buildSuggestions(entry.getKey(), entry.getValue()));
            }
            writer.warn("");
        }
        if (arguments.getDefaultConfigStability() != null || arguments.getConfigStability() != null || arguments.getPackageStability() != null) {
            boolean needCR = false;
            if (!scanResults.getExcludedFeatures().isEmpty()) {
                String msg = arguments.getConfigStability() == null ? "" : " at the '" + arguments.getConfigStability() + "' stability level";
                writer.warn("The following features would be disabled if provisioning a server" + msg + ". Make sure to set the '--config-stability-level=' option:");
                needCR = true;
                for (Layer l : scanResults.getExcludedFeatures().keySet()) {
                    writer.warn(l.getName() + " features:");
                    for (String f : scanResults.getExcludedFeatures().get(l)) {
                        writer.warn("- " + f);
                    }
                }
            }
            if (!scanResults.getExcludedPackages().isEmpty()) {
                writer.warn("The following packages would be disabled if provisioning a server at the '"
                        + arguments.getPackageStability() + "' stability level for packages:");
                needCR = true;
                writer.warn("packages:");
                for (String p : scanResults.getExcludedPackages()) {
                    writer.warn("- " + p);
                }
            }
            if (needCR) {
                writer.info("");
            }
        }
        String suggestedConfigs = buildSuggestions(scanResults.getSuggestions().getSuggestedConfigurations());
        String suggestedBuildTimeConfigs = buildSuggestions(scanResults.getSuggestions().getBuildTimeConfigurations());

        if (arguments.isSuggest()) {
            writer.info("suggestions");
            if (scanResults.getSuggestions().getPossibleAddOns().isEmpty() && scanResults.getSuggestions().getPossibleProfiles().isEmpty() && suggestedConfigs.isEmpty() && suggestedBuildTimeConfigs.isEmpty()) {
                writer.info("none");
            } else {
                if (!suggestedBuildTimeConfigs.isEmpty()) {
                    writer.info("\n* you could set the following configuration at provisioning time");
                    writer.info(suggestedBuildTimeConfigs);
                }
                if (!suggestedConfigs.isEmpty()) {
                    writer.info("\n* you could set the following configuration at runtime");
                    writer.info(suggestedConfigs);
                }
                if (!scanResults.getSuggestions().getPossibleAddOns().isEmpty()) {
                    writer.info("* you could enable the following add-ons:");
                    Map> sortedAddOns = new TreeMap<>();
                    for (AddOn addOn : scanResults.getSuggestions().getPossibleAddOns()) {
                        Set addons = sortedAddOns.get(addOn.getFamily());
                        if (addons == null) {
                            addons = new TreeSet<>();
                            sortedAddOns.put(addOn.getFamily(), addons);
                        }
                        addons.add(addOn);
                    }
                    StringBuilder possibleBuilder = new StringBuilder();
                    for (String family : sortedAddOns.keySet()) {
                        possibleBuilder.append("  - ").append(family).append(" add-ons:\n");
                        for (AddOn l : sortedAddOns.get(family)) {
                            possibleBuilder.append("    - ").append(l.getName()).append(l.getDescription() != null ? " : "
                                    + l.getDescription() : "").append("\n");
                        }
                    }
                    writer.info(possibleBuilder);
                }
                if (!scanResults.getSuggestions().getPossibleProfiles().isEmpty()) {
                    writer.info("* you could enable profiles:");
                    StringBuilder profilesBuilder = new StringBuilder();
                    for (String l : scanResults.getSuggestions().getPossibleProfiles()) {
                        profilesBuilder.append("  - ").append(l).append("\n");
                    }
                    writer.info(profilesBuilder);
                }
            }
        } else {
            if (!scanResults.getSuggestions().getPossibleAddOns().isEmpty() || !scanResults.getSuggestions().getPossibleAddOns().isEmpty() || !suggestedConfigs.isEmpty() || !suggestedBuildTimeConfigs.isEmpty()) {
                writer.info("Some suggestions have been found. You could enable suggestions with the " + (arguments.isCli() ? "--suggest" : "true") + " option.");
            }
        }
    }

    private String buildSuggestions(Map> map) throws Exception {
        StringBuilder suggestedConfigsBuilder = new StringBuilder();
        for (Layer l : map.keySet()) {
            suggestedConfigsBuilder.append(buildSuggestions(l, map.get(l)));
        }
        return suggestedConfigsBuilder.toString();
    }

    private String buildSuggestions(Layer layer, Set envs) throws Exception {
        StringBuilder suggestedConfigsBuilder = new StringBuilder();
        Set envVars = new TreeSet<>();
        Set properties = new TreeSet<>();
        Iterator it = envs.iterator();
        while (it.hasNext()) {
            Env e = it.next();
            if (e.isProperty()) {
                properties.add(e);
            } else {
                envVars.add(e);
            }
        }
        if (!envVars.isEmpty()) {
            suggestedConfigsBuilder.append("\n").append(layer.getName()).append(" environment variables:\n");
            if (configResolver != null) {
                ResolvedEnvs resolvedEnvs = configResolver.getResolvedEnvs(layer, envVars);
                if (resolvedEnvs != null) {
                    envVars.removeAll(resolvedEnvs.getEnvs());
                    if (envVars.isEmpty()) {
                        suggestedConfigsBuilder.append(" - ").append("Resolver " + resolvedEnvs.getName()).append(" resolved all env variables.");
                    } else {
                        suggestedConfigsBuilder.append(" - ").append("Resolver " + resolvedEnvs.getName()).append(" resolved the following env variables:\n");
                        for (Env env : resolvedEnvs.getEnvs()) {
                            suggestedConfigsBuilder.append("  - ").append(env.getName() + "\n");

                        }
                    }
                }
            }
            Iterator it2 = envVars.iterator();
            while (it2.hasNext()) {
                Env e = it2.next();
                suggestedConfigsBuilder.append(" - ").append(e.getName()).append("=").append(e.getDescription());
                if (it2.hasNext()) {
                    suggestedConfigsBuilder.append("\n");
                }
            }
        }
        if (!properties.isEmpty()) {
            suggestedConfigsBuilder.append("\n").append(layer.getName()).append(" system properties:\n");
            Iterator it2 = properties.iterator();
            while (it2.hasNext()) {
                Env e = it2.next();
                suggestedConfigsBuilder.append(" -D").append(e.getName()).append("=").append(e.getDescription());
                if (it2.hasNext()) {
                    suggestedConfigsBuilder.append("\n");
                }
            }
        }
        return suggestedConfigsBuilder.toString();
    }}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy