This is an automated email from the ASF dual-hosted git repository.

sijie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/bookkeeper.git


The following commit(s) were added to refs/heads/master by this push:
     new 78f8623  ISSUE #945: Enabling BookieShell for LocalBookKeeper
78f8623 is described below

commit 78f862362ef35d07f2889de81e1c64c1f1cc9b2a
Author: cguttapalem <[email protected]>
AuthorDate: Thu Jan 11 07:09:13 2018 -0800

    ISSUE #945: Enabling BookieShell for LocalBookKeeper
    
    Descriptions of the changes in this PR:
    
    We should be able to execute BookieShell commands against bookies of 
LocalBookkeeper
    
    eg. for Zookeeper/Metadata Operation
    ./bookkeeper shell -localbookie listbookies -rw
    
    eg. for Bookie operation
    ./bookkeeper shell -localbookie 10.3.27.190:5000 lastmark
    ./bookkeeper shell -localbookie 10.3.27.190:5000 listfilesondisc
    
    Master Issue: #945
    
    Author: cguttapalem <[email protected]>
    
    Reviewers: Enrico Olivelli <[email protected]>, Sijie Guo 
<[email protected]>
    
    This closes #946 from reddycharan/localbookkeeper, closes #945
---
 bookkeeper-server/bin/bookkeeper                   |  12 +++
 bookkeeper-server/conf/bkenv.sh                    |   3 +
 .../org/apache/bookkeeper/bookie/BookieShell.java  |   2 +-
 .../apache/bookkeeper/util/LocalBookKeeper.java    | 104 ++++++++++++++++++---
 4 files changed, 109 insertions(+), 12 deletions(-)

diff --git a/bookkeeper-server/bin/bookkeeper b/bookkeeper-server/bin/bookkeeper
index b3510e3..ca2d279 100755
--- a/bookkeeper-server/bin/bookkeeper
+++ b/bookkeeper-server/bin/bookkeeper
@@ -56,6 +56,8 @@ DEFAULT_LOG_CONF=$BK_HOME/conf/log4j.properties
 
 source $BK_HOME/conf/bkenv.sh
 
+LOCALBOOKIES_CONFIG_DIR="${LOCALBOOKIES_CONFIG_DIR:-/tmp/localbookies-config}"
+
 # Check for the java to use
 if [[ -z $JAVA_HOME ]]; then
   JAVA=$(which java)
@@ -184,6 +186,16 @@ shift
 
 if [ $COMMAND == "shell" ]; then
   DEFAULT_LOG_CONF=$BK_HOME/conf/log4j.shell.properties
+    if [[ $1 == "-localbookie"  ]]; then
+        if [[ $2 == *:* ]];
+        then
+            BOOKIE_CONF=$LOCALBOOKIES_CONFIG_DIR/$2.conf
+            shift 2
+        else
+            BOOKIE_CONF=$LOCALBOOKIES_CONFIG_DIR/baseconf.conf
+            shift
+        fi
+    fi
 fi
 
 if [ -z "$BOOKIE_CONF" ]; then
diff --git a/bookkeeper-server/conf/bkenv.sh b/bookkeeper-server/conf/bkenv.sh
index c85b295..2eaeece 100644
--- a/bookkeeper-server/conf/bkenv.sh
+++ b/bookkeeper-server/conf/bkenv.sh
@@ -48,3 +48,6 @@
 
 #Entry formatter class to format entries.
 #ENTRY_FORMATTER_CLASS=
+
+# this default config dir should match the 'localBookiesConfigDirectory' 
config value in the conf file of LocalBookKeeper
+#LOCALBOOKIES_CONFIG_DIR=/tmp/localbookies-config
\ No newline at end of file
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java
index 039132b..fcd6329 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java
@@ -2513,7 +2513,7 @@ public class BookieShell implements Tool {
     }
 
     private void printShellUsage() {
-        System.err.println("Usage: bookkeeper shell [-ledgeridformat 
<hex/long/uuid>] "
+        System.err.println("Usage: bookkeeper shell [-localbookie 
[<host:port>]] [-ledgeridformat <hex/long/uuid>] "
                 + "[-entryformat <hex/string>] [-conf configuration] 
<command>");
         System.err.println("where command is one of:");
         List<String> commandNames = new ArrayList<String>();
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/util/LocalBookKeeper.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/util/LocalBookKeeper.java
index 7347ba5..d4ecccc 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/util/LocalBookKeeper.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/util/LocalBookKeeper.java
@@ -24,11 +24,14 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
+import java.io.PrintWriter;
 import java.net.InetAddress;
 import java.net.Socket;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 
+import org.apache.bookkeeper.bookie.Bookie;
 import org.apache.bookkeeper.bookie.BookieException;
 import org.apache.bookkeeper.client.BKException;
 import org.apache.bookkeeper.conf.AbstractConfiguration;
@@ -61,12 +64,13 @@ public class LocalBookKeeper {
     }
 
     public LocalBookKeeper(int numberOfBookies) {
-        this(numberOfBookies, 5000);
+        this(numberOfBookies, 5000, defaultLocalBookiesConfigDir);
     }
 
-    public LocalBookKeeper(int numberOfBookies, int initialPort) {
+    public LocalBookKeeper(int numberOfBookies, int initialPort, String 
localBookiesConfigDirName) {
         this.numberOfBookies = numberOfBookies;
         this.initialPort = initialPort;
+        this.localBookiesConfigDir = new File(localBookiesConfigDirName);
         LOG.info("Running {} bookie(s) on zkServer {}.", this.numberOfBookies);
     }
 
@@ -74,6 +78,7 @@ public class LocalBookKeeper {
     private static int zooKeeperDefaultPort = 2181;
     private static int zkSessionTimeOut = 5000;
     private static Integer bookieDefaultInitialPort = 5000;
+    private static String defaultLocalBookiesConfigDir = 
"/tmp/localbookies-config";
 
     //BookKeeper variables
     File journalDirs[];
@@ -81,6 +86,7 @@ public class LocalBookKeeper {
     ServerConfiguration bsConfs[];
     Integer initialPort = 5000;
 
+    File localBookiesConfigDir;
     /**
      * @param maxCC
      *          Max Concurrency of Client
@@ -172,6 +178,15 @@ public class LocalBookKeeper {
         bs = new BookieServer[numberOfBookies];
         bsConfs = new ServerConfiguration[numberOfBookies];
 
+        if (localBookiesConfigDir.exists() && localBookiesConfigDir.isFile()) {
+            throw new IOException("Unable to create LocalBookiesConfigDir, 
since there is a file at "
+                    + localBookiesConfigDir.getAbsolutePath());
+        }
+        if (!localBookiesConfigDir.exists() && 
!localBookiesConfigDir.mkdirs()) {
+            throw new IOException(
+                    "Unable to create LocalBookiesConfigDir - " + 
localBookiesConfigDir.getAbsolutePath());
+        }
+
         for (int i = 0; i < numberOfBookies; i++) {
             if (null == baseConf.getJournalDirNameWithoutDefault()) {
                 journalDirs[i] = IOUtils.createTempDir("localbookkeeper" + 
Integer.toString(i), dirSuffix);
@@ -210,7 +225,7 @@ public class LocalBookKeeper {
                 }
             }
 
-            bsConfs[i] = new ServerConfiguration(baseConf);
+            bsConfs[i] = new ServerConfiguration((ServerConfiguration) 
baseConf.clone());
 
             // If the caller specified ephemeral ports then use ephemeral 
ports for all
             // the bookies else use numBookie ports starting at initialPort
@@ -225,13 +240,35 @@ public class LocalBookKeeper {
                                   + zooKeeperDefaultPort);
             }
 
-
             bsConfs[i].setJournalDirName(journalDirs[i].getPath());
             bsConfs[i].setLedgerDirNames(ledgerDirs);
 
+            // write config into file before start so we can know what's wrong 
if start failed
+            String fileName = Bookie.getBookieAddress(bsConfs[i]).toString() + 
".conf";
+            serializeLocalBookieConfig(bsConfs[i], fileName);
+
             bs[i] = new BookieServer(bsConfs[i]);
             bs[i].start();
         }
+
+        /*
+         * baseconf.conf is needed because for executing any BookieShell 
command
+         * of Metadata/Zookeeper Operation nature we need a valid conf file
+         * having correct zk details and this could be used for running any 
such
+         * bookieshell commands if bookieid is not provided as parameter to
+         * bookkeeper shell operation. for eg:
+         * "./bookkeeper shell localbookie listbookies -rw". But for execution
+         * shell command of bookie Operation nature we need to provide 
bookieid,
+         * for eg "./bookkeeper shell -localbookie 10.3.27.190:5000 lastmark",
+         * so this shell command would use '10.3.27.190:5000.conf' file
+         */
+        ServerConfiguration baseConfWithCorrectZKServers = new 
ServerConfiguration(
+                (ServerConfiguration) baseConf.clone());
+        if (null == baseConf.getZkServers()) {
+            baseConfWithCorrectZKServers
+                    .setZkServers(InetAddress.getLocalHost().getHostAddress() 
+ ":" + zooKeeperDefaultPort);
+        }
+        serializeLocalBookieConfig(baseConfWithCorrectZKServers, 
"baseconf.conf");
     }
 
     public static void startLocalBookies(String zkHost,
@@ -243,7 +280,7 @@ public class LocalBookKeeper {
         ServerConfiguration conf = new ServerConfiguration();
         startLocalBookiesInternal(
                 conf, zkHost, zkPort, numBookies, shouldStartZK,
-                initialBookiePort, true, "test", null);
+                initialBookiePort, true, "test", null, 
defaultLocalBookiesConfigDir);
     }
 
     public static void startLocalBookies(String zkHost,
@@ -255,7 +292,7 @@ public class LocalBookKeeper {
             throws Exception {
         startLocalBookiesInternal(
                 conf, zkHost, zkPort, numBookies, shouldStartZK,
-                initialBookiePort, true, "test", null);
+                initialBookiePort, true, "test", null, 
defaultLocalBookiesConfigDir);
     }
 
     public static void startLocalBookies(String zkHost,
@@ -268,7 +305,7 @@ public class LocalBookKeeper {
         ServerConfiguration conf = new ServerConfiguration();
         startLocalBookiesInternal(
                 conf, zkHost, zkPort, numBookies, shouldStartZK,
-                initialBookiePort, true, dirSuffix, null);
+                initialBookiePort, true, dirSuffix, null, 
defaultLocalBookiesConfigDir);
     }
 
     static void startLocalBookiesInternal(ServerConfiguration conf,
@@ -279,9 +316,10 @@ public class LocalBookKeeper {
                                           int initialBookiePort,
                                           boolean stopOnExit,
                                           String dirSuffix,
-                                          String zkDataDir)
+                                          String zkDataDir,
+                                          String localBookiesConfigDirName)
             throws Exception {
-        LocalBookKeeper lb = new LocalBookKeeper(numBookies, 
initialBookiePort);
+        LocalBookKeeper lb = new LocalBookKeeper(numBookies, 
initialBookiePort, localBookiesConfigDirName);
 
         ZooKeeperServerShim zks = null;
         File zkTmpDir = null;
@@ -291,6 +329,13 @@ public class LocalBookKeeper {
                 File zkDataDirFile = null;
                 if (zkDataDir != null) {
                     zkDataDirFile = new File(zkDataDir);
+                    if (zkDataDirFile.exists() && zkDataDirFile.isFile()) {
+                        throw new IOException("Unable to create zkDataDir, 
since there is a file at "
+                                + zkDataDirFile.getAbsolutePath());
+                    }
+                    if (!zkDataDirFile.exists() && !zkDataDirFile.mkdirs()) {
+                        throw new IOException("Unable to create zkDataDir - " 
+ zkDataDirFile.getAbsolutePath());
+                    }
                 }
                 zkTmpDir = IOUtils.createTempDir("zookeeper", dirSuffix, 
zkDataDirFile);
                 zkTmpDir.deleteOnExit();
@@ -329,6 +374,38 @@ public class LocalBookKeeper {
         }
     }
 
+    /**
+     * Serializes the config object to the specified file in 
localBookiesConfigDir.
+     *
+     * @param localBookieConfig
+     *         config object which has to be serialized
+     * @param fileName
+     *         name of the file
+     * @throws IOException
+     */
+    private void serializeLocalBookieConfig(ServerConfiguration 
localBookieConfig, String fileName) throws IOException {
+        File localBookieConfFile = new File(localBookiesConfigDir, fileName);
+        if (localBookieConfFile.exists() && !localBookieConfFile.delete()) {
+            throw new IOException(
+                    "Unable to delete the existing LocalBookieConfigFile - " + 
localBookieConfFile.getAbsolutePath());
+        }
+        if (!localBookieConfFile.createNewFile()) {
+            throw new IOException("Unable to create new File - " + 
localBookieConfFile.getAbsolutePath());
+        }
+        Iterator<String> keys = localBookieConfig.getKeys();
+        try (PrintWriter writer = new PrintWriter(localBookieConfFile, 
"UTF-8")) {
+            while (keys.hasNext()) {
+                String key = keys.next().toString();
+                String[] values = localBookieConfig.getStringArray(key);
+                StringBuilder concatenatedValue = new StringBuilder(values[0]);
+                for (int i = 1; i < values.length; i++) {
+                    concatenatedValue.append("," + values[i]);
+                }
+                writer.println(key + "=" + concatenatedValue.toString());
+            }
+        }
+    }
+
     public static void main(String[] args) throws Exception, SecurityException 
{
         if (args.length < 1) {
             usage();
@@ -355,17 +432,22 @@ public class LocalBookKeeper {
             zkDataDir = args[2];
         }
 
+        String localBookiesConfigDirName = defaultLocalBookiesConfigDir;
+        if (args.length >= 4) {
+            localBookiesConfigDirName = args[3];
+        }
+
         startLocalBookiesInternal(
                 conf, zooKeeperDefaultHost, zooKeeperDefaultPort,
                 numBookies, true, bookieDefaultInitialPort,
                 false, "test",
-                zkDataDir);
+                zkDataDir, localBookiesConfigDirName);
     }
 
     private static void usage() {
         System.err.println(
                 "Usage: LocalBookKeeper number-of-bookies [path to bookie 
config] "
-                + "[path to create ZK data directory at]");
+                + "[path to create ZK data directory at] [path to 
LocalBookiesConfigDir]");
     }
 
     public static boolean waitForServerUp(String hp, long timeout) {

-- 
To stop receiving notification emails like this one, please contact
['"[email protected]" <[email protected]>'].

Reply via email to