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

com.centurylink.mdw.dataaccess.file.VcsArchiver Maven / Gradle / Ivy

There is a newer version: 6.1.39
Show newest version
/*
 * Copyright (C) 2017 CenturyLink, Inc.
 *
 * 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 com.centurylink.mdw.dataaccess.file;

import com.centurylink.mdw.cli.Checkpoint;
import com.centurylink.mdw.config.PropertyManager;
import com.centurylink.mdw.dataaccess.AssetRevision;
import com.centurylink.mdw.dataaccess.DataAccessException;
import com.centurylink.mdw.dataaccess.DbAccess;
import com.centurylink.mdw.dataaccess.VersionControl;
import com.centurylink.mdw.util.DateHelper;
import com.centurylink.mdw.util.log.LoggerUtil;
import com.centurylink.mdw.util.log.StandardLogger;
import com.centurylink.mdw.util.timer.ProgressMonitor;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class VcsArchiver {

    private static StandardLogger logger = LoggerUtil.getStandardLogger();
    private File assetDir;
    private File tempDir;
    private File tempArchiveDir;
    private VersionControl versionControl;
    private static final String ARCHIVE = "Archive";
    private File archiveDir;

    private ProgressMonitor progressMonitor;

    public ProgressMonitor getProgressMonitor() {
        return progressMonitor;
    }

    private List tempPkgDirs;
    private List tempPkgArchiveDirs;

    public VcsArchiver(File assetDir, File tempDir, VersionControl versionControl,
            ProgressMonitor progressMonitor) {
        this.assetDir = assetDir;
        this.tempDir = tempDir;
        this.versionControl = versionControl;
        this.progressMonitor = progressMonitor;
    }

    private static boolean inProgress = false;
    public static synchronized boolean setInProgress() {
        if (inProgress)
            return false;

        inProgress = true;
        return true;
    }

    public void backup() throws DataAccessException, IOException {
        backup(null);
    }

    /**
     * Save current package(s) to temp dir. Uses 40% of progressMonitor.
     *
     * @param Asset:
     *            com.centurylink.mdw.demo.intro/readme.md (entire package will
     *            be archived). Package: com.centurylink.mdw.demo. All Packages:
     *            null.
     *
     */
    public void backup(String path) throws DataAccessException, IOException {
        try {
            // isolate the package name
            if (path != null) {
                int slash = path.lastIndexOf('/');
                if (slash > 0)
                    path = path.substring(0, slash);
            }

            // copy all packages from the asset dir to the temp dir
            LoaderPersisterVcs oldLoader = new LoaderPersisterVcs("mdw", assetDir, versionControl,
                    new MdwBaselineData());
            List oldPkgDirs = oldLoader.getPackageDirs(true);
            progressMonitor.subTask("Backing up existing package(s) in: " + assetDir);
            progressMonitor.progress(10);
            tempDir = new File(
                    tempDir + "/AssetBackup_" + DateHelper.filenameDateToString(new Date()));
            if (!tempDir.exists()) {
                if (!tempDir.mkdirs())
                    throw new IOException(
                            "Unable to create temp directory: " + tempDir.getAbsolutePath());
            }
            tempArchiveDir = new File(tempDir + "/Archive");
            if (!tempArchiveDir.exists()) {
                if (!tempArchiveDir.mkdirs())
                    throw new IOException(
                            "Unable to create temp directory: " + tempArchiveDir.getAbsolutePath());
            }
            progressMonitor.progress(10);
            progressMonitor.subTask("Copying packages to temps: " + tempDir.getAbsolutePath() + ", "
                    + tempArchiveDir.getAbsolutePath());
            tempPkgDirs = new ArrayList(oldPkgDirs.size());
            tempPkgArchiveDirs = new ArrayList(oldPkgDirs.size());
            for (PackageDir oldPkgDir : oldPkgDirs) {
                if (path == null || path.equals(oldPkgDir.getPackageName())) {
                    File myTempDir = oldPkgDir.isArchive() ? tempArchiveDir : tempDir;
                    File tempPkgDir = new File(myTempDir + "/" + oldPkgDir.getPackageName() + " v"
                            + oldPkgDir.getPackageVersion());
                    progressMonitor.subTask("  -- " + tempPkgDir.getName());
                    oldLoader.copyPkg(oldPkgDir, tempPkgDir);
                    if (oldPkgDir.isArchive())
                        tempPkgArchiveDirs.add(tempPkgDir);
                    else
                        tempPkgDirs.add(tempPkgDir);
                }
            }
            progressMonitor.progress(20);
        }
        catch (Exception e) {
            inProgress = false;
            throw e;
        }
    }

    /**
     * Move replaced package(s) to archive from temp (those not found in updated
     * asset folder). Uses 40% of progressMonitor.
     */
    public void archive() throws DataAccessException, IOException {
        archive(false);
    }

    /**
     * Reverses previous pre-import from backup.
     *
     */
    private void revertImport(LoaderPersisterVcs newLoader, boolean deleteBackups)
            throws IOException {
        for (File prevPkg : tempPkgDirs) {
            File restoreDest = new File(assetDir + "/" + prevPkg.getName()
                    .substring(0, prevPkg.getName().indexOf(" v")).replace('.', '/'));
            if (restoreDest.exists())
                newLoader.deletePkg(restoreDest);
            newLoader.copyPkg(prevPkg, restoreDest);
        }
        if (deleteBackups) {
            progressMonitor.subTask("Removing temp backups: " + tempDir + ", " + tempArchiveDir);
            try {
                newLoader.delete(tempDir);
            }
            catch (Throwable ex) {
                logger.severeException(ex.getMessage(), ex);
            }
        }

    }

    /**
     * Adding asset Git references to ASSET_REF table. Uses 40% of
     * progressMonitor.
     */
    public void archive(boolean deleteBackups) throws DataAccessException, IOException {
        try {
            LoaderPersisterVcs newLoader = new LoaderPersisterVcs("mdw", assetDir, versionControl,
                    new MdwBaselineData());
            archiveDir = new File(assetDir + "/" + ARCHIVE);
            if (!archiveDir.exists()) {
                if (tempPkgArchiveDirs != null && tempPkgArchiveDirs.size() > 0) {
                    // The Archive directory got deleted - Restore it here
                    progressMonitor
                    .subTask("Restoring Archive assets: " + archiveDir.getAbsolutePath());
                    for (File tempPkgDir : tempPkgArchiveDirs) {
                        File archiveDest = new File(archiveDir + "/" + tempPkgDir.getName());
                        if (archiveDest.exists())
                            newLoader.deletePkg(archiveDest);
                        newLoader.copyPkg(tempPkgDir, archiveDest);
                    }
                }
            }
            List newPkgDirs = newLoader.getPackageDirs(false);
            VersionControlGit vcGit = versionControl instanceof VersionControlGit ? (VersionControlGit) versionControl : null;
            if (!"true".equals(PropertyManager.getProperty("mdw.suppress.asset.version.check"))) {
                List flaggedAssets = null;
                List conflictingAssets = null;
                PackageDir newPkg = null;
                // Check for user errors - i.e. older version asset present in newer
                // pkg, or same version asset but modified in newer pkg
                progressMonitor.subTask("Checking for asset version inconsistencies");
                versionControl.clear();
                for (File prevPkg : tempPkgDirs) {
                    String simplePkgName = prevPkg.getName().substring(0,
                            prevPkg.getName().indexOf(" v"));
                    newPkg = null;
                    for (PackageDir item : newPkgDirs) {
                        if (simplePkgName.equals(item.getPackageName())) {
                            newPkg = item;
                            break;
                        }
                    }
                    if (newPkg != null) {
                        for (File prevFile : prevPkg.listFiles()) {
                            if (prevFile.isFile()) {
                                AssetFile newFile = newPkg
                                        .getAssetFile(new File(newPkg + "/" + prevFile.getName()));
                                if (newFile != null && newFile.getRevision().getVersion() > 0) {
                                    AssetRevision prevRev = versionControl.getRevision(prevFile);
                                    // Check for trying to import older version
                                    // asset than existing
                                    if (prevRev != null && prevRev.getVersion() > newFile.getRevision()
                                            .getVersion()) {
                                        if (flaggedAssets == null)
                                            flaggedAssets = new ArrayList<>();
                                        flaggedAssets.add(newFile);
                                    }
                                    // Check for trying to import same version asset
                                    // but differs from existing - Always need to
                                    // increment asset version if different
                                    else if (vcGit != null && prevRev != null && prevRev
                                            .getVersion() == newFile.getRevision().getVersion()) {
                                        if (!(vcGit.getGitId(prevFile)
                                                .equals(vcGit.getGitId(newFile)))) {
                                            if (conflictingAssets == null)
                                                conflictingAssets = new ArrayList<>();
                                            conflictingAssets.add(newFile);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if (flaggedAssets != null || conflictingAssets != null) {
                    // Need to restore previous pkgs and error out on asset import
                    progressMonitor.subTask("Found asset(s) version inconsistencies....restoring from backup");
                    revertImport(newLoader, deleteBackups);
                    String message = "";
                    if (flaggedAssets != null) {
                        message += "Failed -- Import would replace the following assets with older versions: \n";
                        for (AssetFile file : flaggedAssets)
                            message += file.getLogicalFile() + " \n";
                    }
                    if (conflictingAssets != null) {
                        message += "Failed -- Import would replace the following modified assets with same versions (version needs incrementing): \n";
                        for (AssetFile file : conflictingAssets)
                            message += file.getLogicalFile() + " \n";
                    }
                    throw new IOException(message);
                }
                progressMonitor.progress(10);
            }
            if (vcGit != null && vcGit.getCommit() != null) {
                progressMonitor.subTask("Adding asset Git references to ASSET_REF table");
                try (DbAccess dbAccess = new DbAccess()) {
                    Checkpoint cp = new Checkpoint(assetDir, versionControl, vcGit.getCommit(),
                            dbAccess.getConnection());
                    cp.updateRefs();
                }
                catch (SQLException | IOException e) {
                    progressMonitor
                    .subTask("Exception occurred in Asset Git ref update. Reverting Import...");
                    revertImport(newLoader, deleteBackups);
                    throw new DataAccessException(e.getMessage());
                }
            }
            else {
                progressMonitor.subTask("Unable to retrieve Git information....restoring from backup");
                revertImport(newLoader, deleteBackups);
                String message = "Failed -- Unable to retrieve Git information for asset packages";
                throw new DataAccessException(message);
            }
            progressMonitor.progress(20);
            if (deleteBackups) {
                progressMonitor.subTask("Removing temp backups: " + tempDir + ", " + tempArchiveDir);
                try {
                    newLoader.delete(tempDir);
                }
                catch (Throwable ex) {
                    logger.severeException(ex.getMessage(), ex);
                }
            }
            progressMonitor.progress(10);
            inProgress = false;
        }
        catch (Exception e) {
            inProgress = false;
            throw e;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy