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

org.flywaydb.core.internal.reports.html.HtmlReportGenerator Maven / Gradle / Ivy

There is a newer version: 10.15.2
Show newest version
/*
 * Copyright (C) Red Gate Software Ltd 2010-2024
 *
 * 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.flywaydb.core.internal.reports.html;

import lombok.CustomLog;
import lombok.experimental.ExtensionMethod;
import org.flywaydb.core.api.configuration.Configuration;
import org.flywaydb.core.api.output.DashboardResult;
import org.flywaydb.core.api.output.HoldingResult;
import org.flywaydb.core.api.output.HtmlResult;
import org.flywaydb.core.api.output.CompositeResult;
import org.flywaydb.core.extensibility.HtmlRenderer;
import org.flywaydb.core.extensibility.HtmlReportSummary;
import org.flywaydb.core.extensibility.LicenseGuard;
import org.flywaydb.core.extensibility.Tier;
import org.flywaydb.core.internal.util.FileUtils;
import org.flywaydb.core.internal.util.StringUtils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.flywaydb.core.internal.util.ClassUtils.getInstallDir;
import static org.flywaydb.core.internal.util.HtmlUtils.getFormattedTimestamp;

@CustomLog
@ExtensionMethod(Tier.class)
public class HtmlReportGenerator {
    private static final List HOLDING_TAB_METADATA = Arrays.asList(
            new HoldingTabMetadata("changes", "ENTERPRISE"),
            new HoldingTabMetadata("drift", "ENTERPRISE"),
            new HoldingTabMetadata("migrate", "OSS"),
            new HoldingTabMetadata("dryrun", "TEAMS", "ENTERPRISE"),
            new HoldingTabMetadata("code", "OSS")
                                                                                      );
    public static final String INSTALL_DIR = getInstallDir(HtmlReportGenerator.class);

    public static String generateHtml(CompositeResult result, Configuration config) {
        Map> groupedResults = result.individualResults.stream().collect(Collectors.groupingBy(HtmlResult::getTimestamp));
        List timestamps = new ArrayList<>(groupedResults.keySet());

        StringBuilder content = new StringBuilder(getBeginning(timestamps));
        for (LocalDateTime timestamp : timestamps) {
            List groupedResult = groupedResults.get(timestamp);

            DashboardResult dashboardResult = new DashboardResult();
            dashboardResult.setOperation("dashboard");
            dashboardResult.setResults(groupedResult);
            dashboardResult.setTimestamp(timestamp);

            groupedResult.add(0, dashboardResult);

            String currentTier = LicenseGuard.getTierAsString(config);

            for (HoldingTabMetadata holdingTabMetadata : HOLDING_TAB_METADATA) {
                String holdingTab = holdingTabMetadata.getName();
                if (groupedResult.stream().noneMatch(t -> holdingTab.equals(t.getOperation()) && !t.isLicenseFailed())) {
                    String htmlFile = FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/holdingTabs/" + holdingTab + ".html");
                    HoldingResult holdingResult = new HoldingResult();
                    if (holdingTabMetadata.getSupportedEditions().get(0) != "OSS" && !holdingTabMetadata.getSupportedEditions().contains(currentTier)) {
                        htmlFile = FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/upgradeTabs/" + holdingTab + ".html");
                        if (groupedResult.stream().anyMatch(t -> t.getOperation().equals(holdingTab))) {
                            HtmlResult htmlResult = groupedResult.stream().filter(t -> t.getOperation().equals(holdingTab)).findFirst().get();
                            holdingResult.setException(htmlResult.exceptionObject);
                        }
                    }
                    String tabTitle = FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/holdingTabs/" + holdingTab + ".txt");
                    holdingResult.setTimestamp(timestamp);
                    holdingResult.setTabTitle(tabTitle.trim());
                    holdingResult.setBodyText(htmlFile);
                    holdingResult.setOperation(holdingTab);
                    groupedResult.add(holdingResult);
                }
            }

            List htmlResults = new ArrayList<>();

            for (HtmlResult htmlResult : groupedResult) {
                if (!htmlResult.isLicenseFailed()) {
                    htmlResults.add(htmlResult);
                }
            }

            String formattedTimestamp = timestamp.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            content.append(getPage(formattedTimestamp, htmlResults, config));
        }

        return content.append(getEnd()).toString();
    }

    private static String getBeginning(List timestamps) {
        return "\n" +
                "\n" +
                "\n" +
                "\n\n" +
                "\n" +
                FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/icons/AddFilled.svg") +
                FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/icons/Calendar.svg") +
                FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/icons/CheckFilled.svg") +
                FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/icons/ClockOutlined.svg") +
                FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/icons/Database.svg") +
                FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/icons/DeleteFilled.svg") +
                FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/icons/Document.svg") +
                FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/icons/EditFilled.svg") +
                FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/icons/ErrorFilled.svg") +
                FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/icons/FeedbackOutlined.svg") +
                FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/icons/flyway-upgrade-icon.svg") +
                FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/icons/InfoOutlined.svg") +
                FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/icons/PipelineFilled.svg") +
                FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/icons/ScriptOutlined.svg") +
                FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/icons/upgrade.svg") +
                FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/icons/WarningFilled.svg") +
                " 
" + "
" + " \n" + "
Flyway Reports
" + //"
" + " " + //"
" + "
\n" + "
\n" + getDropdown(timestamps); } private static String getDropdown(List timestamps) { Collections.sort(timestamps); StringBuilder options = new StringBuilder(); for (int i = 0; i < timestamps.size(); i++) { String timestamp = timestamps.get(i).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); options.append("\n"); } return "
\n" + "\n" + "\n" + "
\n"; } public static HtmlRenderer getRenderer(HtmlResult htmlResult, Configuration config) { HtmlRenderer result = config.getPluginRegister().getPlugins(HtmlRenderer.class).stream() .filter(t -> t.getType().isAssignableFrom(htmlResult.getClass())) .findFirst() .orElse(null); if (result == null) { System.out.println("No renderer found for " + htmlResult.getClass().getName()); } return result; } private static String getPage(String timestamp, List results, Configuration config) { StringBuilder content = new StringBuilder(); content.append("
\n"); content.append(getTabs(results, config)); int tabCount = 0; for (HtmlResult result : results) { content.append(renderTab(result, config, tabCount)); tabCount++; } return content.append("
\n").toString(); } private static String getTabs(List result, Configuration config) { StringBuilder tabs = new StringBuilder(); int tabCount = 0; for (HtmlResult htmlResult : result) { String id2 = htmlResult.getOperation() + "-" + tabCount + "_" + getFormattedTimestamp(htmlResult); String button = "\n"); tabCount++; } return "
\n" + tabs + "
"; } public static String renderTab(HtmlResult result, Configuration config, int tabCount) { HtmlRenderer renderer = getRenderer(result, config); return getTabOpening(result, config, tabCount) + renderTabSummary(result, config) + renderer.render(result, config) + getTabEnding(result); } public static String renderTabSummary(HtmlResult result, Configuration config) { HtmlRenderer renderer = getRenderer(result, config); List summaries = renderer.getHtmlSummary(result); if (summaries == null) { return ""; } String html = "
"; for (HtmlReportSummary s : summaries) { html += "
" + s.getSummaryText() + "
"; } try { String informationalText = FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/infoBlobs/" + result.getOperation() + ".html"); if (StringUtils.hasText(informationalText)) { html += "
" + informationalText + "
"; } } catch (Exception ignore) { } html += "
"; return html; } public static String getTabOpening(HtmlResult result, Configuration config, int tabCount) { return "
\n"; } public static String getTabEnding(HtmlResult result) { String htmlResult = ""; if (result.getException() != null) { htmlResult += "
\n" + "
Flyway Exception: " + result.getException() + "
\n" + "
\n"; } return htmlResult + "
\n"; } public static String getTabId(HtmlResult result, Configuration config, int tabCount) { HtmlRenderer correctRenderer = getRenderer(result, config); return (correctRenderer.tabTitle(result, config) + "_" + tabCount + "_" + getFormattedTimestamp(result)).replace(" ", ""); } private static String getEnd() { String html = "
\n"; html += FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/footer.html"); html += "
\n" + getScript() + "\n"; return html; } public static String getSummaryValueStyled(int value, String color, String backgroundColor) { return getSummaryValueStyled(value, color, "black", backgroundColor, "white"); } public static String getSummaryValueStyled(int value, String color, String defaultColor, String backgroundColor, String defaultBackgroundColor) { color = value > 0 ? color : defaultColor; backgroundColor = value > 0 ? backgroundColor : defaultBackgroundColor; return "" + value + ""; } public static String getSummaryStyle() { return "style=\"background-color: rgb(240 240 240); padding: 20px; border-radius: 5px; color: black; display: flex; justify-content: space-between; clear: both; margin-top: 20px;\""; } public static String getInformationalText(String txt) { return "" + txt + ".\n"; } private static String getScript() { return FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/reportScript.html"); } private static String getBase64EncodedLogo() { InputStream logo = HtmlReportGenerator.class.getClassLoader().getResourceAsStream("logo_base64.txt"); if (logo == null) { LOG.debug("Unable to load logo for check report"); return ""; } return new BufferedReader(new InputStreamReader(logo)).lines().collect(Collectors.toList()).get(0); } private static String getCodeStyle() { return FileUtils.readAsStringFallbackToResource(INSTALL_DIR, "assets/report/report.css"); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy