org.apache.hive.ptest.execution.Phase.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hive.ptest.execution.Phase.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.hive.ptest.execution;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.apache.hive.ptest.execution.LocalCommand.CollectLogPolicy;
import org.apache.hive.ptest.execution.ssh.NonZeroExitCodeException;
import org.apache.hive.ptest.execution.ssh.RemoteCommandResult;
import org.apache.hive.ptest.execution.ssh.SSHExecutionException;
import org.apache.hive.ptest.execution.ssh.SSHResult;
import org.slf4j.Logger;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;

public abstract class Phase {

    protected final List<HostExecutor> hostExecutors;
    private final LocalCommandFactory localCommandFactory;
    private final ImmutableMap<String, String> templateDefaults;
    protected final Logger logger;

    public Phase(List<HostExecutor> hostExecutors, LocalCommandFactory localCommandFactory,
            ImmutableMap<String, String> templateDefaults, Logger logger) {
        super();
        this.hostExecutors = hostExecutors;
        this.localCommandFactory = localCommandFactory;
        this.templateDefaults = templateDefaults;
        this.logger = logger;
    }

    public abstract void execute() throws Throwable;

    // clean prep
    protected void execLocally(String command) throws IOException, InterruptedException, NonZeroExitCodeException {
        CollectLogPolicy localCollector = new CollectLogPolicy(logger);
        command = Templates.getTemplateResult(command, templateDefaults);
        LocalCommand localCmd = localCommandFactory.create(localCollector, command);
        if (localCmd.getExitCode() != 0) {
            throw new NonZeroExitCodeException(
                    String.format("Command '%s' failed with exit status %d and output '%s'", command,
                            localCmd.getExitCode(), localCollector.getOutput()));
        }
    }

    // prep
    protected List<RemoteCommandResult> rsyncFromLocalToRemoteInstances(String localFile, String remoteFile)
            throws Exception {
        List<ListenableFuture<List<ListenableFuture<RemoteCommandResult>>>> futures = Lists.newArrayList();
        for (HostExecutor hostExecutor : hostExecutors) {
            futures.add(hostExecutor.rsyncFromLocalToRemoteInstances(localFile, remoteFile));
        }
        return flatten(futures);
    }

    // clean
    protected List<SSHResult> execHosts(String command) throws Exception {
        List<ListenableFuture<SSHResult>> futures = Lists.newArrayList();
        for (HostExecutor hostExecutor : hostExecutors) {
            futures.add(hostExecutor.exec(command));
        }
        return toListOfResults(futures);
    }

    protected List<SSHResult> execHostsIgnoreErrors(String command) throws Exception {
        List<ListenableFuture<SSHResult>> futures = Lists.newArrayList();
        for (HostExecutor hostExecutor : hostExecutors) {
            futures.add(hostExecutor.execIgnoreAllErrors(command));
        }
        return toListOfResults(futures, false);
    }

    // clean prep
    protected List<RemoteCommandResult> execInstances(String command) throws Exception {
        List<ListenableFuture<RemoteCommandResult>> futures = Lists.newArrayList();
        for (HostExecutor hostExecutor : hostExecutors) {
            futures.addAll(hostExecutor.execInstances(command));
        }
        return toListOfResults(futures);
    }

    protected List<RemoteCommandResult> initalizeHosts() throws Exception {
        List<ListenableFuture<List<RemoteCommandResult>>> futures = Lists.newArrayList();
        ListeningExecutorService executor = MoreExecutors
                .listeningDecorator(Executors.newFixedThreadPool(hostExecutors.size()));
        try {
            for (final HostExecutor hostExecutor : hostExecutors) {
                futures.add(executor.submit(new Callable<List<RemoteCommandResult>>() {
                    @Override
                    public List<RemoteCommandResult> call() throws Exception {
                        return initalizeHost(hostExecutor);
                    }
                }));
            }
            List<RemoteCommandResult> results = Lists.newArrayList();
            for (ListenableFuture<List<RemoteCommandResult>> future : futures) {
                List<RemoteCommandResult> result = future.get();
                if (result != null) {
                    results.addAll(result);
                }
            }
            executor.shutdown();
            return results;
        } finally {
            if (executor.isShutdown()) {
                executor.shutdownNow();
            }
        }
    }

    protected List<RemoteCommandResult> initalizeHost(HostExecutor hostExecutor) throws Exception {
        List<RemoteCommandResult> results = Lists.newArrayList();
        results.add(hostExecutor.exec("killall -q -9 java || true").get());
        TimeUnit.SECONDS.sleep(1);
        // order matters in all of these so block
        results.addAll(toListOfResults(
                hostExecutor.execInstances("rm -rf $localDir/$instanceName/scratch $localDir/$instanceName/logs")));
        results.addAll(toListOfResults(hostExecutor.execInstances("mkdir -p $localDir/$instanceName/logs "
                + "$localDir/$instanceName/maven " + "$localDir/$instanceName/scratch "
                + "$localDir/$instanceName/ivy " + "$localDir/$instanceName/${repositoryName}-source")));
        // order does not matter below, so go wide
        List<ListenableFuture<List<ListenableFuture<RemoteCommandResult>>>> futures = Lists.newArrayList();
        futures.add(hostExecutor.rsyncFromLocalToRemoteInstances("$workingDir/${repositoryName}-source",
                "$localDir/$instanceName/"));
        futures.add(hostExecutor.rsyncFromLocalToRemoteInstances("$workingDir/maven", "$localDir/$instanceName/"));
        futures.add(hostExecutor.rsyncFromLocalToRemoteInstances("$workingDir/ivy", "$localDir/$instanceName/"));
        results.addAll(flatten(futures));
        return results;
    }

    private <T extends RemoteCommandResult> List<T> flatten(
            List<ListenableFuture<List<ListenableFuture<T>>>> futures) throws Exception {
        List<T> results = Lists.newArrayList();
        for (ListenableFuture<List<ListenableFuture<T>>> future : futures) {
            List<ListenableFuture<T>> result = future.get();
            if (result != null) {
                results.addAll(toListOfResults(result));
            }
        }
        return results;
    }

    private <T extends RemoteCommandResult> List<T> toListOfResults(List<ListenableFuture<T>> futures)
            throws Exception {
        return toListOfResults(futures, true);
    }

    private <T extends RemoteCommandResult> List<T> toListOfResults(List<ListenableFuture<T>> futures,
            boolean reportErrors) throws Exception {
        List<T> results = Lists.newArrayList();
        for (T result : Futures.allAsList(futures).get()) {
            if (result != null) {
                if (reportErrors && (result.getException() != null || result.getExitCode() != 0)) {
                    throw new SSHExecutionException(result);
                }
                results.add(result);
            }
        }
        return results;
    }

    protected ImmutableMap<String, String> getTemplateDefaults() {
        return templateDefaults;
    }
}