co.cask.tigon.DistributedMain.java Source code

Java tutorial

Introduction

Here is the source code for co.cask.tigon.DistributedMain.java

Source

/*
 * Copyright  2014 Cask Data, 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 co.cask.tigon;

import co.cask.tigon.app.guice.ProgramRunnerRuntimeModule;
import co.cask.tigon.cli.CLICommands;
import co.cask.tigon.cli.DistributedFlowOperations;
import co.cask.tigon.cli.FlowOperations;
import co.cask.tigon.cli.InvalidCLIArgumentException;
import co.cask.tigon.conf.CConfiguration;
import co.cask.tigon.conf.Constants;
import co.cask.tigon.data.runtime.DataFabricDistributedModule;
import co.cask.tigon.flow.DeployClient;
import co.cask.tigon.guice.ConfigModule;
import co.cask.tigon.guice.DiscoveryRuntimeModule;
import co.cask.tigon.guice.IOModule;
import co.cask.tigon.guice.LocationRuntimeModule;
import co.cask.tigon.guice.TwillModule;
import co.cask.tigon.guice.ZKClientModule;
import co.cask.tigon.metrics.MetricsCollectionService;
import co.cask.tigon.metrics.NoOpMetricsCollectionService;
import co.cask.tigon.utils.ProjectInfo;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
import com.google.common.util.concurrent.Service;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Scopes;
import jline.TerminalFactory;
import jline.console.ConsoleReader;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * Tigon Distributed Main.
 */
public class DistributedMain {
    private static final Logger LOG = LoggerFactory.getLogger(DistributedMain.class);

    private final File localDataDir;
    private final FlowOperations flowOperations;
    private final ConsoleReader consoleReader;

    public DistributedMain(String zkQuorumString, String rootNamespace) throws IOException {
        localDataDir = Files.createTempDir();

        CConfiguration cConf = CConfiguration.create();
        cConf.set(Constants.Zookeeper.QUORUM, zkQuorumString);
        cConf.set(Constants.Location.ROOT_NAMESPACE, rootNamespace);
        cConf.set(Constants.CFG_LOCAL_DATA_DIR, localDataDir.getAbsolutePath());
        cConf.reloadConfiguration();
        Configuration hConf = HBaseConfiguration.create();

        Injector injector = Guice.createInjector(createModules(cConf, hConf));
        flowOperations = injector.getInstance(FlowOperations.class);
        consoleReader = new ConsoleReader();
    }

    private static void usage(boolean error) {
        PrintStream out = (error ? System.err : System.out);
        out.println(
                "Usage:   java -cp lib/*:<hadoop/hbase classpath> co.cask.tigon.DistributedMain <ZooKeeperQuorum> "
                        + "<HDFSNamespace>");
        out.println(
                "Example: java -cp lib/*:$HBASE_CLASSPATH co.cask.tigon.DistributedMain 165.238.239.12:1234/tigon "
                        + "tigon");
        out.println("");
        if (error) {
            throw new IllegalArgumentException();
        }
    }

    public static DistributedMain createDistributedMain(String zkString, String rootNamespace) throws IOException {
        return new DistributedMain(zkString, rootNamespace);
    }

    public static void main(String[] args) {
        System.out.println("Tigon Distributed Client");
        if (args.length > 0) {
            if ("--help".equals(args[0]) || "-h".equals(args[0])) {
                usage(false);
                return;
            }

            if (args.length < 2) {
                usage(true);
            }

            String zkQuorumString = args[0];
            String rootNamespace = args[1];

            DistributedMain main = null;
            try {
                main = createDistributedMain(zkQuorumString, rootNamespace);
                main.startUp(System.out);
            } catch (Exception e) {
                LOG.error(e.getMessage(), e);
            } finally {
                try {
                    if (main != null) {
                        main.shutDown();
                    }
                    TerminalFactory.get().restore();
                } catch (Exception e) {
                    LOG.warn(e.getMessage(), e);
                }
            }
        }
    }

    private void registerShutDownHook() {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                try {
                    shutDown();
                } catch (Throwable e) {
                    LOG.error("Failed to shutdown", e);
                }
            }
        });
    }

    public void startUp(PrintStream out) throws Exception {
        registerShutDownHook();
        flowOperations.startAndWait();
        List<String> commandList = Lists.newArrayList();
        for (CLICommands cliCommand : CLICommands.values()) {
            commandList.add(cliCommand.toString().toLowerCase());
        }
        consoleReader.setPrompt("tigon> ");
        String line;
        while ((line = consoleReader.readLine()) != null) {
            String[] args = line.split("\\s+");
            String command = args[0].toUpperCase();
            try {
                CLICommands cmd = null;
                try {
                    cmd = CLICommands.valueOf(command);
                } catch (IllegalArgumentException e) {
                    out.println("Available Commands : ");
                    out.println(StringUtils.join(commandList, ", "));
                    continue;
                }

                if (args.length < cmd.getArgCount()) {
                    throw new InvalidCLIArgumentException(cmd.printHelp());
                }

                if (cmd.equals(CLICommands.START)) {
                    Map<String, String> runtimeArgs = Maps.newHashMap();
                    if (args.length > cmd.getArgCount()) {
                        try {
                            runtimeArgs = DeployClient
                                    .fromPosixArray(Arrays.copyOfRange(args, cmd.getArgCount(), args.length));
                        } catch (IllegalArgumentException e) {
                            LOG.error("Runtime Args are not in the correct format [ --key1=val1 --key2=val2 ]");
                            continue;
                        }
                    }
                    flowOperations.startFlow(new File(args[1]), args[2], runtimeArgs);
                } else if (cmd.equals(CLICommands.LIST)) {
                    out.println(StringUtils.join(flowOperations.listAllFlows(), ", "));
                } else if (cmd.equals(CLICommands.STOP)) {
                    flowOperations.stopFlow(args[1]);
                } else if (cmd.equals(CLICommands.DELETE)) {
                    flowOperations.deleteFlow(args[1]);
                } else if (cmd.equals(CLICommands.SET)) {
                    flowOperations.setInstances(args[1], args[2], Integer.valueOf(args[3]));
                } else if (cmd.equals(CLICommands.STATUS)) {
                    Service.State state = flowOperations.getStatus(args[1]);
                    String status = (state != null) ? state.toString() : "NOT FOUND";
                    out.println(status);
                } else if (cmd.equals(CLICommands.FLOWLETINFO)) {
                    out.println(String.format("%-20s %s", "Flowlet Name", "Instance Count"));
                    Map<String, Integer> flowletInfoMap = flowOperations.getFlowInfo(args[1]);
                    for (Map.Entry<String, Integer> flowletInfo : flowletInfoMap.entrySet()) {
                        out.println(String.format("%-20s %s", flowletInfo.getKey(), flowletInfo.getValue()));
                    }
                } else if (cmd.equals(CLICommands.DISCOVER)) {
                    for (InetSocketAddress socketAddress : flowOperations.discover(args[1], args[2])) {
                        out.println(String.format("%s:%s", socketAddress.getHostName(), socketAddress.getPort()));
                    }
                } else if (cmd.equals(CLICommands.SHOWLOGS)) {
                    flowOperations.addLogHandler(args[1], System.out);
                } else if (cmd.equals(CLICommands.SERVICEINFO)) {
                    out.println(StringUtils.join(flowOperations.getServices(args[1]), "\n"));
                } else if (cmd.equals(CLICommands.VERSION)) {
                    out.println(ProjectInfo.getVersion().getBuildVersion());
                } else if (cmd.equals(CLICommands.HELP)) {
                    try {
                        out.println(CLICommands.valueOf(args[1].toUpperCase()).printHelp());
                    } catch (IllegalArgumentException e) {
                        out.println("Command Not Found");
                    }
                } else {
                    //QUIT Command
                    break;
                }
            } catch (InvalidCLIArgumentException e) {
                out.println(e.getMessage());
            }
        }
    }

    public void shutDown() {
        try {
            flowOperations.stopAndWait();
            FileUtils.deleteDirectory(localDataDir);
        } catch (Exception e) {
            LOG.warn(e.getMessage(), e);
        }
    }

    private static List<Module> createModules(CConfiguration cConf, Configuration hConf) {
        return ImmutableList.of(new DataFabricDistributedModule(), new ConfigModule(cConf, hConf), new IOModule(),
                new ZKClientModule(), new TwillModule(), new LocationRuntimeModule().getDistributedModules(),
                new DiscoveryRuntimeModule().getDistributedModules(),
                new ProgramRunnerRuntimeModule().getDistributedModules(), new MetricsClientModule(),
                new AbstractModule() {
                    @Override
                    protected void configure() {
                        bind(FlowOperations.class).to(DistributedFlowOperations.class);
                    }
                });
    }

    private static final class MetricsClientModule extends AbstractModule {
        @Override
        protected void configure() {
            bind(MetricsCollectionService.class).to(NoOpMetricsCollectionService.class).in(Scopes.SINGLETON);
        }
    }
}