ratis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From els...@apache.org
Subject incubator-ratis git commit: RATIS-387. An interactive shell for the logservice
Date Mon, 31 Dec 2018 21:42:23 GMT
Repository: incubator-ratis
Updated Branches:
  refs/heads/master b7b7e7e0e -> 5ae2490de


RATIS-387. An interactive shell for the logservice

Includes instructions on how to start a local quorum and connect the shell to it


Project: http://git-wip-us.apache.org/repos/asf/incubator-ratis/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ratis/commit/5ae2490d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ratis/tree/5ae2490d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ratis/diff/5ae2490d

Branch: refs/heads/master
Commit: 5ae2490deee1cb30347d2c2ec492010a4567a181
Parents: b7b7e7e
Author: Josh Elser <elserj@apache.org>
Authored: Tue Dec 4 22:32:20 2018 -0500
Committer: Josh Elser <elserj@apache.org>
Committed: Mon Dec 31 16:42:13 2018 -0500

----------------------------------------------------------------------
 pom.xml                                         |   5 +
 ratis-logservice/README.md                      |  51 +++++++
 ratis-logservice/pom.xml                        |  14 +-
 .../ratis/logservice/server/ServerOpts.java     |   2 +-
 .../apache/ratis/logservice/shell/Command.java  |  15 +++
 .../ratis/logservice/shell/CommandFactory.java  |  50 +++++++
 .../ratis/logservice/shell/LogServiceShell.java | 133 +++++++++++++++++++
 .../logservice/shell/LogServiceShellOpts.java   |   8 ++
 .../shell/commands/CreateLogCommand.java        |  30 +++++
 .../shell/commands/DeleteLogCommand.java        |  32 +++++
 .../logservice/shell/commands/ExitCommand.java  |  20 +++
 .../logservice/shell/commands/HelpCommand.java  |  23 ++++
 .../shell/commands/ListLogsCommand.java         |  42 ++++++
 .../shell/commands/PutToLogCommand.java         |  36 +++++
 .../shell/commands/ReadLogCommand.java          |  53 ++++++++
 15 files changed, 508 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/5ae2490d/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 9d8a427..4d4282d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -355,6 +355,11 @@
         <artifactId>mockito-all</artifactId>
         <version>1.8.5</version>
       </dependency>
+	    <dependency>
+	      <groupId>org.jline</groupId>
+	      <artifactId>jline</artifactId>
+	      <version>3.9.0</version>
+	    </dependency>
     </dependencies>
   </dependencyManagement>
 

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/5ae2490d/ratis-logservice/README.md
----------------------------------------------------------------------
diff --git a/ratis-logservice/README.md b/ratis-logservice/README.md
new file mode 100644
index 0000000..1827594
--- /dev/null
+++ b/ratis-logservice/README.md
@@ -0,0 +1,51 @@
+# Ratis LogService
+
+
+## Example shell
+
+Build:
+```bash
+$ mvn install
+```
+
+Change to logservice dectory:
+```bash
+$ cd ratis-log-service
+```
+
+Launch Metadata daemons:
+```bash
+$ mvn exec:java -Dexec.mainClass=org.apache.ratis.logservice.server.MetadataServer -Dexec.args="-p
9991 -d $HOME/logservice1 -h localhost -q localhost:9991,localhost:9992,localhost:9993"
+```
+```bash
+$ mvn exec:java -Dexec.mainClass=org.apache.ratis.logservice.server.MetadataServer -Dexec.args="-p
9992 -d $HOME/logservice2 -h localhost -q localhost:9991,localhost:9992,localhost:9993"
+```
+```bash
+$ mvn exec:java -Dexec.mainClass=org.apache.ratis.logservice.server.MetadataServer -Dexec.args="-p
9993 -d $HOME/logservice3 -h localhost -q localhost:9991,localhost:9992,localhost:9993"
+```
+
+Above, we have started three daemons that will form a quorum to act as the "LogService Metadata".
They will track what
+logs exist and the RAFT qs which service those logs.
+
+Launch Worker daemons:
+```bash
+$ mvn exec:java -Dexec.mainClass=org.apache.ratis.logservice.server.LogServer -Dexec.args="-p
9951 -d $HOME/worker1 -h localhost -q localhost:9991,localhost:9992,localhost:9993"
+```
+```bash
+$ mvn exec:java -Dexec.mainClass=org.apache.ratis.logservice.server.LogServer -Dexec.args="-p
9952 -d $HOME/worker2 -h localhost -q localhost:9991,localhost:9992,localhost:9993"
+```
+```bash
+$ mvn exec:java -Dexec.mainClass=org.apache.ratis.logservice.server.LogServer -Dexec.args="-p
9953 -d $HOME/worker3 -h localhost -q localhost:9991,localhost:9992,localhost:9993"
+```
+
+Now, we have started three daemons which can service a single LogStream. They will rep to
the Metadata q,
+and the Metadata quorum will choose three of them to form a RAFT quorum to "host" a single
Log.
+
+Note: the `q` option here references to the Metadata quorum, not the worker quorum as is
the case for the Metadata daemons.
+
+Launch client:
+```bash
+$ mvn exec:java -Dexec.mainClass=org.apache.ratis.logservice.shell.LogServiceShell -Dexec.args="-q
localhost:9990,localhost:9991,localhost:9992"
+```
+
+This command will launch an interactive shell that you can use to interact with the system.

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/5ae2490d/ratis-logservice/pom.xml
----------------------------------------------------------------------
diff --git a/ratis-logservice/pom.xml b/ratis-logservice/pom.xml
index 6c49231..a06218b 100644
--- a/ratis-logservice/pom.xml
+++ b/ratis-logservice/pom.xml
@@ -178,6 +178,15 @@
       <artifactId>ratis-netty</artifactId>
       <groupId>org.apache.ratis</groupId>
     </dependency>
+    <!-- CLI dependencies -->
+    <dependency>
+      <groupId>com.beust</groupId>
+      <artifactId>jcommander</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.jline</groupId>
+      <artifactId>jline</artifactId>
+    </dependency>
     <!-- Third-party dependencies -->
     <dependency>
       <groupId>org.slf4j</groupId>
@@ -241,10 +250,5 @@
       <artifactId>mockito-all</artifactId>
       <scope>test</scope>
     </dependency>
-      <dependency>
-          <groupId>com.beust</groupId>
-          <artifactId>jcommander</artifactId>
-          <version>1.72</version>
-      </dependency>
   </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/5ae2490d/ratis-logservice/src/main/java/org/apache/ratis/logservice/server/ServerOpts.java
----------------------------------------------------------------------
diff --git a/ratis-logservice/src/main/java/org/apache/ratis/logservice/server/ServerOpts.java
b/ratis-logservice/src/main/java/org/apache/ratis/logservice/server/ServerOpts.java
index 18e4ba6..7ca9f90 100644
--- a/ratis-logservice/src/main/java/org/apache/ratis/logservice/server/ServerOpts.java
+++ b/ratis-logservice/src/main/java/org/apache/ratis/logservice/server/ServerOpts.java
@@ -38,7 +38,7 @@ public class ServerOpts {
   }
 
   @Parameter(names = {"-h", "--hostname"}, description = "Hostname")
-  private String host;
+  private String host = "localhost";
 
   @Parameter(names = {"-p", "--port"}, description = "Port number")
   private int port = -1;

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/5ae2490d/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/Command.java
----------------------------------------------------------------------
diff --git a/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/Command.java
b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/Command.java
new file mode 100644
index 0000000..4d68792
--- /dev/null
+++ b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/Command.java
@@ -0,0 +1,15 @@
+package org.apache.ratis.logservice.shell;
+
+import org.apache.ratis.logservice.client.LogServiceClient;
+import org.jline.reader.LineReader;
+import org.jline.terminal.Terminal;
+
+/**
+ * Represents a single command in the shell. Each command must be stateless.
+ */
+public interface Command {
+
+  String getHelpMessage();
+
+  void run(Terminal terminal, LineReader lineReader, LogServiceClient client, String[] args);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/5ae2490d/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/CommandFactory.java
----------------------------------------------------------------------
diff --git a/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/CommandFactory.java
b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/CommandFactory.java
new file mode 100644
index 0000000..161cf18
--- /dev/null
+++ b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/CommandFactory.java
@@ -0,0 +1,50 @@
+package org.apache.ratis.logservice.shell;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import org.apache.ratis.logservice.shell.commands.CreateLogCommand;
+import org.apache.ratis.logservice.shell.commands.DeleteLogCommand;
+import org.apache.ratis.logservice.shell.commands.ExitCommand;
+import org.apache.ratis.logservice.shell.commands.HelpCommand;
+import org.apache.ratis.logservice.shell.commands.ListLogsCommand;
+import org.apache.ratis.logservice.shell.commands.PutToLogCommand;
+import org.apache.ratis.logservice.shell.commands.ReadLogCommand;
+
+public class CommandFactory {
+  private static final Map<String,Command> KNOWN_COMMANDS = cacheCommands();
+
+  private static Map<String,Command> cacheCommands() {
+    Map<String,Command> commands = new HashMap<>();
+    ExitCommand exitCommand = new ExitCommand();
+
+    // Ensure all keys are lowercase -- see the same logic in #create(String).
+    commands.put("create", new CreateLogCommand());
+    commands.put("put", new PutToLogCommand());
+    commands.put("read", new ReadLogCommand());
+    commands.put("delete", new DeleteLogCommand());
+    commands.put("exit", exitCommand);
+    commands.put("quit", exitCommand);
+    commands.put("help", new HelpCommand());
+    commands.put("list", new ListLogsCommand());
+
+    return Collections.unmodifiableMap(commands);
+  }
+
+  public static Map<String,Command> getCommands() {
+    return KNOWN_COMMANDS;
+  }
+
+  private CommandFactory() {}
+
+  /**
+   * Returns an instance of the command to run given the name, else null.
+   * Be aware that Command instances are singletons and do not retain state.
+   */
+  public static Command create(String commandName) {
+    // Normalize the command name to lowercase
+    return KNOWN_COMMANDS.get(Objects.requireNonNull(commandName).toLowerCase());
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/5ae2490d/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/LogServiceShell.java
----------------------------------------------------------------------
diff --git a/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/LogServiceShell.java
b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/LogServiceShell.java
new file mode 100644
index 0000000..bb669b7
--- /dev/null
+++ b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/LogServiceShell.java
@@ -0,0 +1,133 @@
+package org.apache.ratis.logservice.shell;
+
+import java.io.IOException;
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Map.Entry;
+import java.util.Objects;
+
+import org.apache.ratis.logservice.client.LogServiceClient;
+import org.apache.ratis.logservice.shell.commands.ExitCommand;
+import org.jline.reader.EndOfFileException;
+import org.jline.reader.History;
+import org.jline.reader.LineReader;
+import org.jline.reader.LineReaderBuilder;
+import org.jline.reader.UserInterruptException;
+import org.jline.reader.impl.DefaultHighlighter;
+import org.jline.reader.impl.history.DefaultHistory;
+import org.jline.terminal.Terminal;
+import org.jline.terminal.TerminalBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.beust.jcommander.JCommander;
+
+/**
+ * An interactive shell that can interact with a LogService instance.
+ */
+public class LogServiceShell {
+  private static Logger LOG = LoggerFactory.getLogger(LogServiceShell.class);
+
+  private static final String PROMPT = "logservice> ";
+
+  private final Terminal terminal;
+  private final LineReader lineReader;
+  private final LogServiceClient client;
+
+  public LogServiceShell(Terminal terminal, LineReader reader, LogServiceClient client) {
+    this.terminal = Objects.requireNonNull(terminal);
+    this.lineReader = Objects.requireNonNull(reader);
+    this.client = Objects.requireNonNull(client);
+  }
+
+  public void run() {
+    while (true) {
+      // Read and sanitize the input
+      String line;
+      try {
+        line = lineReader.readLine(PROMPT);
+      } catch (UserInterruptException e) {
+        continue;
+      } catch (EndOfFileException e) {
+        break;
+      }
+      if (line == null) {
+        continue;
+      }
+      line = line.trim();
+
+      // Construct the Command and args to pass to that command
+      Entry<Command,String[]> pair = parseCommand(line);
+      if (pair == null) {
+        continue;
+      }
+      Command command = pair.getKey();
+      String[] commandArgs = pair.getValue();
+
+      // Our "exit" or "quit"
+      if (command instanceof ExitCommand) {
+        break;
+      }
+
+      // Run the command
+      command.run(terminal, lineReader, client, commandArgs);
+
+      // Flush a newline to the screen.
+      terminal.writer().flush();
+    }
+    terminal.writer().println("Bye!");
+    terminal.writer().flush();
+  }
+
+  Entry<Command,String[]> parseCommand(String line) {
+    String[] words = line.split("\\s+");
+    if (words.length == 0) {
+      return null;
+    }
+
+    String commandWord = words[0];
+    Command command = CommandFactory.create(commandWord);
+    // If we have no command to run, return null.
+    if (command == null) {
+      return null;
+    }
+
+    // Pull off the "command" name
+    String[] args = Arrays.copyOfRange(words, 1, words.length);
+
+    return new AbstractMap.SimpleEntry<>(command, args);
+  }
+
+  public static void main(String[] args) throws Exception {
+    final Terminal terminal = TerminalBuilder.builder()
+        .system(true)
+        .build();
+
+    History defaultHistory = new DefaultHistory();
+    // Register a shutdown-hook per JLine documentation to save history
+    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+      try {
+        defaultHistory.save();
+      } catch (IOException e) {
+        LOG.debug("Failed to save terminal history", e);
+      }
+    }));
+
+    final LineReader lineReader = LineReaderBuilder.builder()
+        .terminal(terminal)
+        .highlighter(new DefaultHighlighter())
+        .history(defaultHistory)
+        .build();
+
+    LogServiceShellOpts opts = new LogServiceShellOpts();
+    JCommander.newBuilder()
+        .addObject(opts)
+        .build()
+        .parse(args);
+
+    try (LogServiceClient logServiceClient = new LogServiceClient(opts.metaQuorum)) {
+      LogServiceShell client = new LogServiceShell(terminal, lineReader, logServiceClient);
+      client.run();
+    }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/5ae2490d/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/LogServiceShellOpts.java
----------------------------------------------------------------------
diff --git a/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/LogServiceShellOpts.java
b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/LogServiceShellOpts.java
new file mode 100644
index 0000000..22742c5
--- /dev/null
+++ b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/LogServiceShellOpts.java
@@ -0,0 +1,8 @@
+package org.apache.ratis.logservice.shell;
+
+import com.beust.jcommander.Parameter;
+
+public class LogServiceShellOpts {
+  @Parameter(names = {"--meta-quorum", "-q"})
+  public String metaQuorum;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/5ae2490d/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/CreateLogCommand.java
----------------------------------------------------------------------
diff --git a/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/CreateLogCommand.java
b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/CreateLogCommand.java
new file mode 100644
index 0000000..dc42e81
--- /dev/null
+++ b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/CreateLogCommand.java
@@ -0,0 +1,30 @@
+package org.apache.ratis.logservice.shell.commands;
+
+import org.apache.ratis.logservice.api.LogName;
+import org.apache.ratis.logservice.api.LogStream;
+import org.apache.ratis.logservice.client.LogServiceClient;
+import org.apache.ratis.logservice.shell.Command;
+import org.jline.reader.LineReader;
+import org.jline.terminal.Terminal;
+
+public class CreateLogCommand implements Command {
+
+  @Override public String getHelpMessage() {
+    return "`create` - Creates a new log with the given name";
+  }
+
+  @Override
+  public void run(Terminal terminal, LineReader lineReader, LogServiceClient client, String[]
args) {
+    if (args.length != 1) {
+      terminal.writer().println("ERROR - Usage: create <name>");
+      return;
+    }
+    String logName = args[0];
+    try (LogStream stream = client.createLog(LogName.of(logName))) {
+      terminal.writer().println("Created log '" + logName + "'");
+    } catch (Exception e) {
+      terminal.writer().println("Error creating log '" + logName + "'");
+      e.printStackTrace(terminal.writer());
+    }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/5ae2490d/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/DeleteLogCommand.java
----------------------------------------------------------------------
diff --git a/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/DeleteLogCommand.java
b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/DeleteLogCommand.java
new file mode 100644
index 0000000..d589f8e
--- /dev/null
+++ b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/DeleteLogCommand.java
@@ -0,0 +1,32 @@
+package org.apache.ratis.logservice.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.ratis.logservice.api.LogName;
+import org.apache.ratis.logservice.client.LogServiceClient;
+import org.apache.ratis.logservice.shell.Command;
+import org.jline.reader.LineReader;
+import org.jline.terminal.Terminal;
+
+public class DeleteLogCommand implements Command {
+
+  @Override public String getHelpMessage() {
+    return "`delete` - deletes the log with the given name.";
+  }
+
+  @Override
+  public void run(Terminal terminal, LineReader lineReader, LogServiceClient client, String[]
args) {
+    if (args.length != 1) {
+      terminal.writer().println("ERROR - Usage: delete <name>");
+      return;
+    }
+    String logName = args[0];
+    try {
+      client.deleteLog(LogName.of(logName));
+      terminal.writer().println("Deleted log '" + logName + "'");
+    } catch (IOException e) {
+      terminal.writer().println("Error deleting log '" + logName + "'");
+      e.printStackTrace(terminal.writer());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/5ae2490d/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/ExitCommand.java
----------------------------------------------------------------------
diff --git a/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/ExitCommand.java
b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/ExitCommand.java
new file mode 100644
index 0000000..e5c25d7
--- /dev/null
+++ b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/ExitCommand.java
@@ -0,0 +1,20 @@
+package org.apache.ratis.logservice.shell.commands;
+
+import org.apache.ratis.logservice.client.LogServiceClient;
+import org.apache.ratis.logservice.shell.Command;
+import org.jline.reader.LineReader;
+import org.jline.terminal.Terminal;
+
+public class ExitCommand implements Command {
+
+  @Override public String getHelpMessage() {
+    return "`exit` -- Exits this shell.";
+  }
+
+  @Override
+  public void run(Terminal terminal, LineReader lineReader, LogServiceClient client, String[]
args) {
+    throw new IllegalStateException("This command should be be invoked");
+  }
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/5ae2490d/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/HelpCommand.java
----------------------------------------------------------------------
diff --git a/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/HelpCommand.java
b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/HelpCommand.java
new file mode 100644
index 0000000..ccb121f
--- /dev/null
+++ b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/HelpCommand.java
@@ -0,0 +1,23 @@
+package org.apache.ratis.logservice.shell.commands;
+
+import org.apache.ratis.logservice.client.LogServiceClient;
+import org.apache.ratis.logservice.shell.Command;
+import org.apache.ratis.logservice.shell.CommandFactory;
+import org.jline.reader.LineReader;
+import org.jline.terminal.Terminal;
+
+public class HelpCommand implements Command {
+
+  @Override public String getHelpMessage() {
+    return "`help` - Prints this help message";
+  }
+
+  @Override
+  public void run(Terminal terminal, LineReader lineReader, LogServiceClient client, String[]
args) {
+    CommandFactory.getCommands()
+        .values()
+        .stream()
+        .forEach((c) -> terminal.writer().println(c.getHelpMessage()));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/5ae2490d/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/ListLogsCommand.java
----------------------------------------------------------------------
diff --git a/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/ListLogsCommand.java
b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/ListLogsCommand.java
new file mode 100644
index 0000000..5896c09
--- /dev/null
+++ b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/ListLogsCommand.java
@@ -0,0 +1,42 @@
+package org.apache.ratis.logservice.shell.commands;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.ratis.logservice.api.LogInfo;
+import org.apache.ratis.logservice.client.LogServiceClient;
+import org.apache.ratis.logservice.shell.Command;
+import org.jline.reader.LineReader;
+import org.jline.terminal.Terminal;
+
+public class ListLogsCommand implements Command {
+
+  @Override
+  public String getHelpMessage() {
+    return "`list` - List the available logs";
+  }
+
+  @Override
+  public void run(Terminal terminal, LineReader lineReader, LogServiceClient client, String[]
args) {
+    if (args.length != 0) {
+      terminal.writer().println("ERROR - Usage: list");
+      return;
+    }
+
+    try {
+      List<LogInfo> logs = client.listLogs();
+      StringBuilder sb = new StringBuilder();
+      for (LogInfo log : logs) {
+        if (sb.length() > 0) {
+          sb.append("\n");
+        }
+        sb.append(log.getLogName().getName());
+      }
+      terminal.writer().println(sb.toString());
+    } catch (IOException e) {
+      terminal.writer().println("Failed to list available logs");
+      e.printStackTrace(terminal.writer());
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/5ae2490d/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/PutToLogCommand.java
----------------------------------------------------------------------
diff --git a/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/PutToLogCommand.java
b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/PutToLogCommand.java
new file mode 100644
index 0000000..048d6be
--- /dev/null
+++ b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/PutToLogCommand.java
@@ -0,0 +1,36 @@
+package org.apache.ratis.logservice.shell.commands;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.ratis.logservice.api.LogName;
+import org.apache.ratis.logservice.api.LogStream;
+import org.apache.ratis.logservice.api.LogWriter;
+import org.apache.ratis.logservice.client.LogServiceClient;
+import org.apache.ratis.logservice.shell.Command;
+import org.jline.reader.LineReader;
+import org.jline.terminal.Terminal;
+
+public class PutToLogCommand implements Command {
+
+  @Override public String getHelpMessage() {
+    return "`put` - Appends a value to a log";
+  }
+
+  @Override
+  public void run(Terminal terminal, LineReader lineReader, LogServiceClient client, String[]
args) {
+    if (args.length != 2) {
+      terminal.writer().println("ERROR - Usage: put <name> <value>");
+      return;
+    }
+    String name = args[0];
+    String value = args[1];
+    try (LogStream stream = client.getLog(LogName.of(name));
+        LogWriter writer = stream.createWriter()) {
+      writer.write(ByteBuffer.wrap(value.getBytes(StandardCharsets.UTF_8)));
+    } catch (Exception e) {
+      terminal.writer().println("Error writing to log");
+      e.printStackTrace(terminal.writer());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/5ae2490d/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/ReadLogCommand.java
----------------------------------------------------------------------
diff --git a/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/ReadLogCommand.java
b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/ReadLogCommand.java
new file mode 100644
index 0000000..c7f0d24
--- /dev/null
+++ b/ratis-logservice/src/main/java/org/apache/ratis/logservice/shell/commands/ReadLogCommand.java
@@ -0,0 +1,53 @@
+package org.apache.ratis.logservice.shell.commands;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+import org.apache.ratis.logservice.api.LogName;
+import org.apache.ratis.logservice.api.LogReader;
+import org.apache.ratis.logservice.api.LogStream;
+import org.apache.ratis.logservice.client.LogServiceClient;
+import org.apache.ratis.logservice.shell.Command;
+import org.jline.reader.LineReader;
+import org.jline.terminal.Terminal;
+
+public class ReadLogCommand implements Command {
+
+  @Override public String getHelpMessage() {
+    return "`read` - Reads all values from the given log";
+  }
+
+  @Override
+  public void run(Terminal terminal, LineReader lineReader, LogServiceClient client, String[]
args) {
+    if (args.length != 1) {
+      terminal.writer().println("ERROR - Usage: read <name>");
+      return;
+    }
+    String logName = args[0];
+    try (LogStream stream = client.getLog(LogName.of(logName));
+        LogReader reader = stream.createReader()) {
+      long firstId = stream.getStartRecordId();
+      long lastId = stream.getLastRecordId();
+      StringBuilder sb = new StringBuilder();
+      int i = 0;
+      List<ByteBuffer> records = reader.readBulk((int) (lastId - firstId));
+      for (ByteBuffer record : records) {
+        if (sb.length() > 0) {
+          sb.append(", ");
+        }
+        sb.append(i).append(":");
+        if (record != null) {
+          String strData = new String(record.array(), record.arrayOffset(), record.remaining(),
StandardCharsets.UTF_8);
+          sb.append(strData);
+        }
+      }
+      sb.insert(0, "[");
+      sb.append("]");
+      terminal.writer().println(sb.toString());
+    } catch (Exception e) {
+      terminal.writer().println("Failed to read from log");
+      e.printStackTrace(terminal.writer());
+    }
+  }
+}


Mime
View raw message