org.apache.accumulo.miniclusterImpl.MiniAccumuloClusterControl.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.accumulo.miniclusterImpl.MiniAccumuloClusterControl.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.accumulo.miniclusterImpl;

import static java.util.Objects.requireNonNull;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.apache.accumulo.cluster.ClusterControl;
import org.apache.accumulo.gc.SimpleGarbageCollector;
import org.apache.accumulo.master.Master;
import org.apache.accumulo.minicluster.ServerType;
import org.apache.accumulo.miniclusterImpl.MiniAccumuloClusterImpl.ProcessInfo;
import org.apache.accumulo.monitor.Monitor;
import org.apache.accumulo.server.util.Admin;
import org.apache.accumulo.tracer.TraceServer;
import org.apache.accumulo.tserver.TabletServer;
import org.apache.zookeeper.server.ZooKeeperServerMain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Maps;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

public class MiniAccumuloClusterControl implements ClusterControl {
    private static final Logger log = LoggerFactory.getLogger(MiniAccumuloClusterControl.class);

    protected MiniAccumuloClusterImpl cluster;

    Process zooKeeperProcess = null;
    Process masterProcess = null;
    Process gcProcess = null;
    Process monitor = null;
    Process tracer = null;
    final List<Process> tabletServerProcesses = new ArrayList<>();

    public MiniAccumuloClusterControl(MiniAccumuloClusterImpl cluster) {
        requireNonNull(cluster);
        this.cluster = cluster;
    }

    public void start(ServerType server) throws IOException {
        start(server, null);
    }

    @Override
    public int exec(Class<?> clz, String[] args) throws IOException {
        Process p = cluster.exec(clz, args).getProcess();
        int exitCode;
        try {
            exitCode = p.waitFor();
        } catch (InterruptedException e) {
            log.warn("Interrupted waiting for process to exit", e);
            Thread.currentThread().interrupt();
            throw new IOException(e);
        }
        return exitCode;
    }

    @SuppressFBWarnings(value = "PATH_TRAVERSAL_IN", justification = "code runs in same security context as user who provided input file name")
    @Override
    public Entry<Integer, String> execWithStdout(Class<?> clz, String[] args) throws IOException {
        ProcessInfo pi = cluster.exec(clz, args);
        int exitCode;
        try {
            exitCode = pi.getProcess().waitFor();
        } catch (InterruptedException e) {
            log.warn("Interrupted waiting for process to exit", e);
            Thread.currentThread().interrupt();
            throw new IOException(e);
        }

        return Maps.immutableEntry(exitCode, pi.readStdOut());
    }

    @Override
    public void adminStopAll() throws IOException {
        Process p = cluster.exec(Admin.class, "stopAll").getProcess();
        try {
            p.waitFor();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IOException(e);
        }
        if (p.exitValue() != 0) {
            throw new IOException("Failed to run `accumulo admin stopAll`");
        }
    }

    @Override
    public synchronized void startAllServers(ServerType server) throws IOException {
        start(server, null);
    }

    @Override
    public synchronized void start(ServerType server, String hostname) throws IOException {
        start(server, Collections.emptyMap(), Integer.MAX_VALUE);
    }

    public synchronized void start(ServerType server, Map<String, String> configOverrides, int limit)
            throws IOException {
        if (limit <= 0) {
            return;
        }

        switch (server) {
        case TABLET_SERVER:
            synchronized (tabletServerProcesses) {
                int count = 0;
                for (int i = tabletServerProcesses.size(); count < limit
                        && i < cluster.getConfig().getNumTservers(); i++, ++count) {
                    tabletServerProcesses
                            .add(cluster._exec(TabletServer.class, server, configOverrides).getProcess());
                }
            }
            break;
        case MASTER:
            if (masterProcess == null) {
                masterProcess = cluster._exec(Master.class, server, configOverrides).getProcess();
            }
            break;
        case ZOOKEEPER:
            if (zooKeeperProcess == null) {
                zooKeeperProcess = cluster._exec(ZooKeeperServerMain.class, server, configOverrides,
                        cluster.getZooCfgFile().getAbsolutePath()).getProcess();
            }
            break;
        case GARBAGE_COLLECTOR:
            if (gcProcess == null) {
                gcProcess = cluster._exec(SimpleGarbageCollector.class, server, configOverrides).getProcess();
            }
            break;
        case MONITOR:
            if (monitor == null) {
                monitor = cluster._exec(Monitor.class, server, configOverrides).getProcess();
            }
            break;
        case TRACER:
            if (tracer == null) {
                tracer = cluster._exec(TraceServer.class, server, configOverrides).getProcess();
            }
            break;
        default:
            throw new UnsupportedOperationException("Cannot start process for " + server);
        }
    }

    @Override
    public synchronized void stopAllServers(ServerType server) throws IOException {
        stop(server);
    }

    public void stop(ServerType server) throws IOException {
        stop(server, null);
    }

    @Override
    public synchronized void stop(ServerType server, String hostname) throws IOException {
        switch (server) {
        case MASTER:
            if (masterProcess != null) {
                try {
                    cluster.stopProcessWithTimeout(masterProcess, 30, TimeUnit.SECONDS);
                } catch (ExecutionException | TimeoutException e) {
                    log.warn("Master did not fully stop after 30 seconds", e);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    masterProcess = null;
                }
            }
            break;
        case GARBAGE_COLLECTOR:
            if (gcProcess != null) {
                try {
                    cluster.stopProcessWithTimeout(gcProcess, 30, TimeUnit.SECONDS);
                } catch (ExecutionException | TimeoutException e) {
                    log.warn("Garbage collector did not fully stop after 30 seconds", e);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    gcProcess = null;
                }
            }
            break;
        case ZOOKEEPER:
            if (zooKeeperProcess != null) {
                try {
                    cluster.stopProcessWithTimeout(zooKeeperProcess, 30, TimeUnit.SECONDS);
                } catch (ExecutionException | TimeoutException e) {
                    log.warn("ZooKeeper did not fully stop after 30 seconds", e);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    zooKeeperProcess = null;
                }
            }
            break;
        case TABLET_SERVER:
            synchronized (tabletServerProcesses) {
                try {
                    for (Process tserver : tabletServerProcesses) {
                        try {
                            cluster.stopProcessWithTimeout(tserver, 30, TimeUnit.SECONDS);
                        } catch (ExecutionException | TimeoutException e) {
                            log.warn("TabletServer did not fully stop after 30 seconds", e);
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                        }
                    }
                } finally {
                    tabletServerProcesses.clear();
                }
            }
            break;
        case MONITOR:
            if (monitor != null) {
                try {
                    cluster.stopProcessWithTimeout(monitor, 30, TimeUnit.SECONDS);
                } catch (ExecutionException | TimeoutException e) {
                    log.warn("Monitor did not fully stop after 30 seconds", e);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    monitor = null;
                }
            }
            break;
        case TRACER:
            if (tracer != null) {
                try {
                    cluster.stopProcessWithTimeout(tracer, 30, TimeUnit.SECONDS);
                } catch (ExecutionException | TimeoutException e) {
                    log.warn("Tracer did not fully stop after 30 seconds", e);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    tracer = null;
                }
            }
            break;
        default:
            throw new UnsupportedOperationException("ServerType is not yet supported " + server);
        }

    }

    @Override
    public void signal(ServerType server, String hostname, String signal) throws IOException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void suspend(ServerType server, String hostname) throws IOException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void resume(ServerType server, String hostname) throws IOException {
        throw new UnsupportedOperationException();
    }

    public void killProcess(ServerType type, ProcessReference procRef)
            throws ProcessNotFoundException, InterruptedException {
        boolean found = false;
        switch (type) {
        case MASTER:
            if (procRef.getProcess().equals(masterProcess)) {
                try {
                    cluster.stopProcessWithTimeout(masterProcess, 30, TimeUnit.SECONDS);
                } catch (ExecutionException | TimeoutException e) {
                    log.warn("Master did not fully stop after 30 seconds", e);
                }
                masterProcess = null;
                found = true;
            }
            break;
        case TABLET_SERVER:
            synchronized (tabletServerProcesses) {
                for (Process tserver : tabletServerProcesses) {
                    if (procRef.getProcess().equals(tserver)) {
                        tabletServerProcesses.remove(tserver);
                        try {
                            cluster.stopProcessWithTimeout(tserver, 30, TimeUnit.SECONDS);
                        } catch (ExecutionException | TimeoutException e) {
                            log.warn("TabletServer did not fully stop after 30 seconds", e);
                        }
                        found = true;
                        break;
                    }
                }
            }
            break;
        case ZOOKEEPER:
            if (procRef.getProcess().equals(zooKeeperProcess)) {
                try {
                    cluster.stopProcessWithTimeout(zooKeeperProcess, 30, TimeUnit.SECONDS);
                } catch (ExecutionException | TimeoutException e) {
                    log.warn("ZooKeeper did not fully stop after 30 seconds", e);
                }
                zooKeeperProcess = null;
                found = true;
            }
            break;
        case GARBAGE_COLLECTOR:
            if (procRef.getProcess().equals(gcProcess)) {
                try {
                    cluster.stopProcessWithTimeout(gcProcess, 30, TimeUnit.SECONDS);
                } catch (ExecutionException | TimeoutException e) {
                    log.warn("GarbageCollector did not fully stop after 30 seconds", e);
                }
                gcProcess = null;
                found = true;
            }
            break;
        default:
            // Ignore the other types MAC currently doesn't automateE
            found = true;
            break;
        }
        if (!found)
            throw new ProcessNotFoundException();
    }

    @Override
    public void kill(ServerType server, String hostname) throws IOException {
        stop(server, hostname);
    }

}