Create 'fluo remove' command #991
diff --git a/modules/api/src/main/java/org/apache/fluo/api/client/FluoAdmin.java b/modules/api/src/main/java/org/apache/fluo/api/client/FluoAdmin.java
index fb25759..12f43f7 100644
--- a/modules/api/src/main/java/org/apache/fluo/api/client/FluoAdmin.java
+++ b/modules/api/src/main/java/org/apache/fluo/api/client/FluoAdmin.java
@@ -120,6 +120,14 @@
throws AlreadyInitializedException, TableExistsException;
/**
+ * Removes Fluo application and shared configuration in Zookeeper. Shared configuration
+ * consists of all properties except those with
+ * {@value org.apache.fluo.api.config.FluoConfiguration#CONNECTION_PREFIX} prefix.
+ */
+ void remove(InitializationOptions opts)
+ throws AlreadyInitializedException, TableExistsException;
+
+ /**
* Updates shared configuration in Zookeeper. Shared configuration consists of all properties
* except those with {@value org.apache.fluo.api.config.FluoConfiguration#CONNECTION_PREFIX}
* prefix. This method is called if a user has previously called
diff --git a/modules/command/src/main/java/org/apache/fluo/command/FluoRemove.java b/modules/command/src/main/java/org/apache/fluo/command/FluoRemove.java
new file mode 100644
index 0000000..2feb0e7
--- /dev/null
+++ b/modules/command/src/main/java/org/apache/fluo/command/FluoRemove.java
@@ -0,0 +1,92 @@
+/*
+ * 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.fluo.command;
+
+import java.io.File;
+
+import com.beust.jcommander.Parameter;
+import com.google.common.base.Preconditions;
+import org.apache.fluo.api.client.FluoAdmin;
+import org.apache.fluo.api.config.FluoConfiguration;
+import org.apache.fluo.core.client.FluoAdminImpl;
+
+public class FluoRemove {
+
+ public static class RemoveOptions extends CommonOpts {
+
+ @Parameter(names = "-p", required = true, description = "Path to application properties file")
+ private String appPropsPath;
+
+ String getAppPropsPath() {
+ return appPropsPath;
+ }
+
+ public static RemoveOptions parse(String[] args) {
+ RemoveOptions opts = new RemoveOptions();
+ parse("fluo remove", opts, args);
+ return opts;
+ }
+ }
+
+ public static void main(String[] args) {
+ RemoveOptions opts = RemoveOptions.parse(args);
+ File applicationPropsFile = new File(opts.getAppPropsPath());
+ Preconditions.checkArgument(applicationPropsFile.exists(),
+ opts.getAppPropsPath() + " does not exist");
+
+ FluoConfiguration config = CommandUtil.resolveFluoConfig();
+ config.load(applicationPropsFile);
+ config.setApplicationName(opts.getApplicationName());
+ opts.overrideFluoConfig(config);
+
+ if (!config.hasRequiredAdminProps()) {
+ System.err.println("Error - Required properties are not set in " + opts.getAppPropsPath());
+ System.exit(-1);
+ }
+ try {
+ config.validate();
+ } catch (Exception e) {
+ System.err.println("Error - Invalid configuration due to " + e.getMessage());
+ System.exit(-1);
+ }
+
+ try (FluoAdminImpl admin = new FluoAdminImpl(config)) {
+
+ if (admin.applicationRunning()) {
+ System.err.println("Error - The Fluo '" + config.getApplicationName() + "' application"
+ + " is already running and must be stopped before running 'fluo remove'. "
+ + " Aborted remove.");
+ System.exit(-1);
+ }
+
+ FluoAdmin.InitializationOptions initOpts = new FluoAdmin.InitializationOptions();
+ initOpts.setClearZookeeper(true).setClearTable(true);
+ initOpts.setClearTable(true);
+
+ System.out.println("Removing Fluo '" + config.getApplicationName() + "' application using "
+ + opts.getAppPropsPath());
+ try {
+ admin.remove(initOpts);
+ } catch (Exception e) {
+ System.out.println("Remove failed due to the following exception:");
+ e.printStackTrace();
+ System.exit(-1);
+ }
+ System.out.println("Remove is complete.");
+
+ }
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/fluo/core/client/FluoAdminImpl.java b/modules/core/src/main/java/org/apache/fluo/core/client/FluoAdminImpl.java
index e711705..25bb839 100644
--- a/modules/core/src/main/java/org/apache/fluo/core/client/FluoAdminImpl.java
+++ b/modules/core/src/main/java/org/apache/fluo/core/client/FluoAdminImpl.java
@@ -201,6 +201,45 @@
}
}
+ @Override
+ public void remove(InitializationOptions opts)
+ throws AlreadyInitializedException, TableExistsException {
+ if (!config.hasRequiredAdminProps()) {
+ throw new IllegalArgumentException("Admin configuration is missing required properties");
+ }
+ Preconditions.checkArgument(
+ !ZookeeperUtil.parseRoot(config.getInstanceZookeepers()).equals("/"),
+ "The Zookeeper connection string (set by 'fluo.connection.zookeepers') "
+ + " must have a chroot suffix.");
+
+ Connector conn = AccumuloUtil.getConnector(config);
+
+ boolean tableExists = conn.tableOperations().exists(config.getAccumuloTable());
+ // With preconditions met, it's now OK to delete table & zookeeper root (if they exist)
+ if (tableExists) {
+ logger.info("The Accumulo table '{}' will be dropped", config.getAccumuloTable());
+ try {
+ conn.tableOperations().delete(config.getAccumuloTable());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ try {
+ if (rootCurator.checkExists().forPath(appRootDir) != null) {
+ logger.info("Clearing Fluo '{}' application in Zookeeper at {}",
+ config.getApplicationName(), config.getAppZookeepers());
+ rootCurator.delete().deletingChildrenIfNeeded().forPath(appRootDir);
+ }
+ } catch (KeeperException.NoNodeException nne) {
+ // it's ok if node doesn't exist
+ } catch (Exception e) {
+ logger.error("An error occurred deleting Zookeeper root of [" + config.getAppZookeepers()
+ + "], error=[" + e.getMessage() + "]");
+ throw new RuntimeException(e);
+ }
+ }
+
private void initializeApplicationInZooKeeper(Connector conn) throws Exception {
final String accumuloInstanceName = conn.getInstance().getInstanceName();
diff --git a/modules/distribution/src/main/scripts/fluo b/modules/distribution/src/main/scripts/fluo
index 4116669..7239159 100755
--- a/modules/distribution/src/main/scripts/fluo
+++ b/modules/distribution/src/main/scripts/fluo
@@ -66,6 +66,7 @@
echo -e "Usage: fluo <command> (<argument> ...)\n"
echo -e "Possible commands:\n"
echo " init -a <app> -p <appProps> Initializes Fluo application for <app> using <appProps>. Run with -h to see additional args."
+ echo " remove -a <app> -p <appProps> Removes Fluo application for <app> using <appProps>."
echo " classpath Prints the classpath setup in fluo-env.sh"
echo " config -a <app> Prints application configuration stored in Zookeeper for <app>"
echo " get-jars -a <app> -d <dir> Copies <app> jars from DFS to local <dir>"
@@ -184,6 +185,25 @@
java org.apache.fluo.cluster.command.FluoCommand "$basedir" "$HADOOP_PREFIX" "$@"
fi
;;
+remove)
+ if [ -f "$FLUO_CONN_PROPS" ]; then
+ if [[ $2 = *"-h"* ]]; then
+ $JAVA org.apache.fluo.command.FluoRemove -h
+ exit 0
+ fi
+ init_dir=$($JAVA org.apache.fluo.command.FluoInit "${@:2}" --retrieveProperty fluo.observer.init.dir)
+ if [ -d "$init_dir" ]; then
+ echo "Adding $init_dir/* to CLASSPATH"
+ export CLASSPATH="$init_dir/*:$CLASSPATH"
+ fi
+ $JAVA org.apache.fluo.command.FluoRemove "${@:2}"
+ else
+ deprecated_verify_full "$2"
+ check_hadoop
+ export CLASSPATH="$APP_LIB_DIR/*:$CLASSPATH"
+ java org.apache.fluo.cluster.command.FluoCommand "$basedir" "$HADOOP_PREFIX" "$@"
+ fi
+ ;;
oracle)
if [[ $2 = *"-h"* ]]; then
$JAVA org.apache.fluo.command.FluoOracle -h
@@ -208,7 +228,7 @@
java org.apache.fluo.cluster.command.FluoCommand "$basedir" "$HADOOP_PREFIX" "$@"
fi
;;
-ps)
+ps)
jps -m | grep Fluo
;;
list)