/* * 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 gobblin.runtime; import java.io.IOException; import java.util.Arrays; import java.util.Comparator; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import com.google.common.base.Strings; import com.google.common.base.Throwables; import lombok.extern.slf4j.Slf4j; import gobblin.annotation.Alias; import gobblin.configuration.ConfigurationKeys; import gobblin.runtime.cli.CliApplication; import gobblin.runtime.cli.EmbeddedGobblinCliFactory; /** * A Cli to inspect streaming watermarks. */ @Alias(value = "watermarks", description = "Inspect streaming watermarks") @Slf4j public class StateStoreBasedWatermarkStorageCli implements CliApplication { private static final Option HELP = Option.builder("h").longOpt("help").build(); private static final Option ZK = Option.builder("z").longOpt("zk") .desc("Zk connect string").hasArg().build(); private static final Option JOB_NAME = Option.builder("j").longOpt("jobName") .desc("The Job name").hasArg().build(); private static final Option ROOT_DIR = Option.builder("r").longOpt("rootDir") .desc("The State Store Root Directory").hasArg().build(); private static final Option WATCH = Option.builder("w").longOpt("watch") .desc("Watch the watermarks").build(); @Override public void run(String[] args) { Options options = new Options(); options.addOption(HELP); options.addOption(ZK); options.addOption(JOB_NAME); options.addOption(ROOT_DIR); options.addOption(WATCH); CommandLine cli; try { CommandLineParser parser = new DefaultParser(); cli = parser.parse(options, Arrays.copyOfRange(args, 1, args.length)); } catch (ParseException pe) { System.out.println( "Command line parse exception: " + pe.getMessage() ); return; } if (cli.hasOption(HELP.getOpt())) { printUsage(options); return; } TaskState taskState = new TaskState(); String jobName; if (!cli.hasOption(JOB_NAME.getOpt())) { log.error("Need Job Name to be specified --", JOB_NAME.getLongOpt()); throw new RuntimeException("Need Job Name to be specified"); } else { jobName = cli.getOptionValue(JOB_NAME.getOpt()); log.info("Using job name: {}", jobName); } taskState.setProp(ConfigurationKeys.JOB_NAME_KEY, jobName); String zkAddress = "locahost:2181"; if (cli.hasOption(ZK.getOpt())) { zkAddress = cli.getOptionValue(ZK.getOpt()); } log.info("Using zk address : {}", zkAddress); taskState.setProp(StateStoreBasedWatermarkStorage.WATERMARK_STORAGE_TYPE_KEY, "zk"); taskState.setProp("state.store.zk.connectString", zkAddress); if (cli.hasOption(ROOT_DIR.getOpt())) { String rootDir = cli.getOptionValue(ROOT_DIR.getOpt()); taskState.setProp(StateStoreBasedWatermarkStorage.WATERMARK_STORAGE_CONFIG_PREFIX + ConfigurationKeys.STATE_STORE_ROOT_DIR_KEY, rootDir); log.info("Setting root dir to {}", rootDir); } else { log.error("Need root directory specified"); printUsage(options); return; } StateStoreBasedWatermarkStorage stateStoreBasedWatermarkStorage = new StateStoreBasedWatermarkStorage(taskState); final AtomicBoolean stop = new AtomicBoolean(true); if (cli.hasOption(WATCH.getOpt())) { stop.set(false); } try { if (!stop.get()) { Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { stop.set(true); } }); } do { boolean foundWatermark = false; try { for (CheckpointableWatermarkState wmState : stateStoreBasedWatermarkStorage.getAllCommittedWatermarks()) { foundWatermark = true; System.out.println(wmState.getProperties()); } } catch (IOException ie) { Throwables.propagate(ie); } if (!foundWatermark) { System.out.println("No watermarks found."); } if (!stop.get()) { Thread.sleep(1000); } } while (!stop.get()); } catch (Exception e) { Throwables.propagate(e); } } private void printUsage(Options options) { HelpFormatter formatter = new HelpFormatter(); formatter.setOptionComparator(new Comparator<Option>() { @Override public int compare(Option o1, Option o2) { if (o1.isRequired() && !o2.isRequired()) { return -1; } if (!o1.isRequired() && o2.isRequired()) { return 1; } return o1.getOpt().compareTo(o2.getOpt()); } }); String usage = "gobblin watermarks "; formatter.printHelp(usage, options); } }