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

liquibase.change.core.ExecuteShellCommandChange Maven / Gradle / Ivy

There is a newer version: 4.29.2
Show newest version
package liquibase.change.core;

import liquibase.change.AbstractChange;
import liquibase.change.ChangeMetaData;
import liquibase.database.Database;
import liquibase.exception.UnexpectedLiquibaseException;
import liquibase.exception.ValidationErrors;
import liquibase.exception.Warnings;
import liquibase.executor.Executor;
import liquibase.executor.ExecutorService;
import liquibase.executor.LoggingExecutor;
import liquibase.logging.LogFactory;
import liquibase.sql.Sql;
import liquibase.statement.SqlStatement;
import liquibase.statement.core.CommentStatement;
import liquibase.statement.core.RuntimeStatement;
import liquibase.util.StreamUtil;
import liquibase.util.StringUtils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Executes a given shell executable.
 */
public class ExecuteShellCommandChange extends AbstractChange {

    private String executable;
    private List os;
    private List args = new ArrayList();

    public ExecuteShellCommandChange() {
        super("executeCommand", "Execute Shell Command", ChangeMetaData.PRIORITY_DEFAULT);
    }


    public String getExecutable() {
        return executable;
    }

    public void setExecutable(String executable) {
        this.executable = executable;
    }

    public void addArg(String arg) {
        this.args.add(arg);
    }


    public void setOs(String os) {
        this.os = StringUtils.splitAndTrim(os, ",");
    }

    public List getOs() {
        return os;
    }

    @Override
    public ValidationErrors validate(Database database) {
        return new ValidationErrors();
    }


    @Override
    public Warnings warn(Database database) {
        return new Warnings();
    }

    public SqlStatement[] generateStatements(final Database database) {
        boolean shouldRun = true;
        if (os != null && os.size() > 0) {
            String currentOS = System.getProperty("os.name");
            if (!os.contains(currentOS)) {
                shouldRun = false;
                LogFactory.getLogger().info("Not executing on os "+currentOS+" when "+os+" was specified");
            }
        }

    	// check if running under not-executed mode (logging output)
        boolean nonExecutedMode = false;
        Executor executor = ExecutorService.getInstance().getExecutor(database);
        if (executor instanceof LoggingExecutor) {
        	nonExecutedMode = true;
        }
        
        if (shouldRun && !nonExecutedMode) {


            return new SqlStatement[]{new RuntimeStatement() {

                @Override
                public Sql[] generate(Database database) {
                    List commandArray = new ArrayList();
                    commandArray.add(executable);
                    commandArray.addAll(args);

                    try {
                        ProcessBuilder pb = new ProcessBuilder(commandArray);
                        pb.redirectErrorStream(true);
                        Process p = pb.start();
                        int returnCode = 0;
                        try {
                            returnCode = p.waitFor();
                        } catch (InterruptedException e) {
                            ;
                        }

                        ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
                        ByteArrayOutputStream inputStream = new ByteArrayOutputStream();
                        StreamUtil.copy(p.getErrorStream(), errorStream);
                        StreamUtil.copy(p.getInputStream(), inputStream);

                        LogFactory.getLogger().severe(errorStream.toString());
                        LogFactory.getLogger().info(inputStream.toString());

                        if (returnCode != 0) {
                            throw new RuntimeException(getCommandString() + " returned an code of " + returnCode);
                        }
                    } catch (IOException e) {
                        throw new UnexpectedLiquibaseException("Error executing command: " + e);
                    }

                    return null;
                }
            }};
        }
        
        if (nonExecutedMode) {
        	return new SqlStatement[] {
        			new CommentStatement(getCommandString())
        	};
        }
        
        return new SqlStatement[0];
    }

    public String getConfirmationMessage() {
        return "Shell command '" + getCommandString() + "' executed";
    }

    private String getCommandString() {
        return executable + " " + StringUtils.join(args, " ");
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy