From 0ef2dccd0e7cb712a57eab1a689d32e5c8cdd743 Mon Sep 17 00:00:00 2001 From: Malla Sandeep Date: Wed, 17 Apr 2024 14:13:08 +0530 Subject: [PATCH 1/6] added functionality for admin,config,client persistent shell modes. --- .../org/apache/pulsar/shell/PulsarShell.java | 55 +++++++++++++++++-- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java b/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java index 3cc99126fb8d7..7d25ef266145b 100644 --- a/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java +++ b/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java @@ -31,6 +31,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.Scanner; @@ -130,6 +131,30 @@ enum ExecState { IDLE, RUNNING } + enum ShellMode { + ADMIN("admin"), + CLIENT("client"), + CONFIG("config"), + DEFAULT(""); + + final String command; + + ShellMode(String command) { + this.command = command; + } + + private static final Map commandMap = new HashMap<>(); + + static { + for (ShellMode shellMode: values()) { + commandMap.put(shellMode.command, shellMode); + } + } + + public static ShellMode valueOfCommand(String command) { + return commandMap.get(command); + } + } private Properties properties; @Getter private final ConfigStore configStore; @@ -142,6 +167,9 @@ enum ExecState { private InteractiveLineReader reader; private final ConfigShell configShell; private ExecState execState = ExecState.IDLE; + private ShellMode shellMode = ShellMode.DEFAULT; + private String prompt; + private String promptMessage; public PulsarShell(String args[]) throws IOException { this(args, new Properties()); @@ -274,14 +302,13 @@ public void run() throws Exception { new AttributedStringBuilder().style(AttributedStyle.BOLD).append("exit").toAnsi(), new AttributedStringBuilder().style(AttributedStyle.BOLD).append("quit").toAnsi()); output(welcomeMessage, terminal); - String promptMessage; if (configShell.getCurrentConfig() != null) { promptMessage = String.format("%s(%s)", configShell.getCurrentConfig(), getHostFromUrl(serviceUrl)); } else { promptMessage = getHostFromUrl(serviceUrl); } - final String prompt = createPrompt(promptMessage); + prompt = createPrompt(promptMessage); return new InteractiveLineReader() { @Override public String readLine() { @@ -414,18 +441,36 @@ public List readCommand() { return; } execState = ExecState.RUNNING; - final String line = words.stream().collect(Collectors.joining(" ")); - if (StringUtils.isBlank(line)) { + final String inputLine = words.stream().collect(Collectors.joining(" ")); + if (StringUtils.isBlank(inputLine)) { continue; } - if (isQuitCommand(line)) { + if (isQuitCommand(inputLine)) { + if (shellMode != ShellMode.DEFAULT){ + output(String.format("Exiting from %s shell mode", shellMode.command), terminal); + promptMessage = promptMessage.substring(0, promptMessage.lastIndexOf(shellMode.command) - 1); + prompt = createPrompt(promptMessage); + shellMode = ShellMode.DEFAULT; + continue; + } exit(0); return; } + if (shellMode != ShellMode.DEFAULT) { + words.add(0, shellMode.command); + } + final String line = words.stream().collect(Collectors.joining(" ")); if (isHelp(line)) { shellCommander.usage(System.out); continue; } + ShellMode newShellMode = ShellMode.valueOfCommand(line.toLowerCase(Locale.ROOT)); + if (newShellMode != null){ + shellMode = newShellMode; + promptMessage = promptMessage.concat(" ").concat(shellMode.command); + prompt = createPrompt(promptMessage); + continue; + } final ShellCommandsProvider pulsarShellCommandsProvider = getProviderFromArgs(shellCommander, words); if (pulsarShellCommandsProvider == null) { From 55554c7fd364dcf854b993cd6be7f8fc3243a4ea Mon Sep 17 00:00:00 2001 From: Malla Sandeep Date: Wed, 17 Apr 2024 14:35:45 +0530 Subject: [PATCH 2/6] refactored code(naming conventions, method order) --- .../org/apache/pulsar/shell/PulsarShell.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java b/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java index 7d25ef266145b..cbf90985a78cd 100644 --- a/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java +++ b/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java @@ -137,22 +137,22 @@ enum ShellMode { CONFIG("config"), DEFAULT(""); - final String command; - - ShellMode(String command) { - this.command = command; - } - - private static final Map commandMap = new HashMap<>(); + private static final Map COMMAND_MAP = new HashMap<>(); static { for (ShellMode shellMode: values()) { - commandMap.put(shellMode.command, shellMode); + COMMAND_MAP.put(shellMode.command, shellMode); } } + final String command; + + ShellMode(String command) { + this.command = command; + } + public static ShellMode valueOfCommand(String command) { - return commandMap.get(command); + return COMMAND_MAP.get(command); } } private Properties properties; From 68b938aa5553832f5c994053ada96b43fdc7920a Mon Sep 17 00:00:00 2001 From: Malla Sandeep Date: Thu, 18 Apr 2024 14:54:42 +0530 Subject: [PATCH 3/6] review comments: spaces where required, single line variable, promptmessage value stays the same but the prompt varies --- .../org/apache/pulsar/shell/PulsarShell.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java b/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java index cbf90985a78cd..3ea8627d5893a 100644 --- a/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java +++ b/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java @@ -441,14 +441,13 @@ public List readCommand() { return; } execState = ExecState.RUNNING; - final String inputLine = words.stream().collect(Collectors.joining(" ")); - if (StringUtils.isBlank(inputLine)) { + String line = words.stream().collect(Collectors.joining(" ")); + if (StringUtils.isBlank(line)) { continue; } - if (isQuitCommand(inputLine)) { - if (shellMode != ShellMode.DEFAULT){ + if (isQuitCommand(line)) { + if (shellMode != ShellMode.DEFAULT) { output(String.format("Exiting from %s shell mode", shellMode.command), terminal); - promptMessage = promptMessage.substring(0, promptMessage.lastIndexOf(shellMode.command) - 1); prompt = createPrompt(promptMessage); shellMode = ShellMode.DEFAULT; continue; @@ -458,17 +457,16 @@ public List readCommand() { } if (shellMode != ShellMode.DEFAULT) { words.add(0, shellMode.command); + line = shellMode.command + " " + line; } - final String line = words.stream().collect(Collectors.joining(" ")); if (isHelp(line)) { shellCommander.usage(System.out); continue; } ShellMode newShellMode = ShellMode.valueOfCommand(line.toLowerCase(Locale.ROOT)); - if (newShellMode != null){ + if (newShellMode != null) { shellMode = newShellMode; - promptMessage = promptMessage.concat(" ").concat(shellMode.command); - prompt = createPrompt(promptMessage); + prompt = createPrompt(promptMessage + " " + shellMode.command); continue; } From 6cf3f77719fed8b339de9a1fabc7160d8c95efc9 Mon Sep 17 00:00:00 2001 From: Malla Sandeep Date: Thu, 18 Apr 2024 16:18:17 +0530 Subject: [PATCH 4/6] Changed so that switching mode is only possible from default mode. --- .../java/org/apache/pulsar/shell/PulsarShell.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java b/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java index 3ea8627d5893a..ee950d0e7e748 100644 --- a/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java +++ b/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java @@ -458,17 +458,18 @@ public List readCommand() { if (shellMode != ShellMode.DEFAULT) { words.add(0, shellMode.command); line = shellMode.command + " " + line; + } else { + ShellMode newShellMode = ShellMode.valueOfCommand(line.toLowerCase(Locale.ROOT)); + if (newShellMode != null) { + shellMode = newShellMode; + prompt = createPrompt(promptMessage + " " + shellMode.command); + continue; + } } if (isHelp(line)) { shellCommander.usage(System.out); continue; } - ShellMode newShellMode = ShellMode.valueOfCommand(line.toLowerCase(Locale.ROOT)); - if (newShellMode != null) { - shellMode = newShellMode; - prompt = createPrompt(promptMessage + " " + shellMode.command); - continue; - } final ShellCommandsProvider pulsarShellCommandsProvider = getProviderFromArgs(shellCommander, words); if (pulsarShellCommandsProvider == null) { From 96031913a4b8f0107a26ddb54fc44604d1708ac7 Mon Sep 17 00:00:00 2001 From: Malla Sandeep Date: Tue, 10 Sep 2024 16:49:30 +0530 Subject: [PATCH 5/6] Updated so that shellCommander, systemRegistry changes with the shellMode which will help in auto-completion --- .../org/apache/pulsar/shell/PulsarShell.java | 90 +++++++++++++------ 1 file changed, 62 insertions(+), 28 deletions(-) diff --git a/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java b/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java index ee950d0e7e748..86e7b511bf8a2 100644 --- a/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java +++ b/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java @@ -131,6 +131,7 @@ enum ExecState { IDLE, RUNNING } + enum ShellMode { ADMIN("admin"), CLIENT("client"), @@ -140,7 +141,7 @@ enum ShellMode { private static final Map COMMAND_MAP = new HashMap<>(); static { - for (ShellMode shellMode: values()) { + for (ShellMode shellMode : values()) { COMMAND_MAP.put(shellMode.command, shellMode); } } @@ -155,6 +156,7 @@ public static ShellMode valueOfCommand(String command) { return COMMAND_MAP.get(command); } } + private Properties properties; @Getter private final ConfigStore configStore; @@ -290,25 +292,28 @@ public void run() throws Exception { configureHistory(properties, readerBuilder); LineReader reader = readerBuilder.build(); - final String welcomeMessage = - String.format("Welcome to Pulsar shell!\n %s: %s\n %s: %s\n\n" - + "Type %s to get started or try the autocompletion (TAB button).\n" - + "Type %s or %s to end the shell session.\n", - new AttributedStringBuilder().style(AttributedStyle.BOLD).append("Service URL").toAnsi(), - serviceUrl, - new AttributedStringBuilder().style(AttributedStyle.BOLD).append("Admin URL").toAnsi(), - adminUrl, - new AttributedStringBuilder().style(AttributedStyle.BOLD).append("help").toAnsi(), - new AttributedStringBuilder().style(AttributedStyle.BOLD).append("exit").toAnsi(), - new AttributedStringBuilder().style(AttributedStyle.BOLD).append("quit").toAnsi()); - output(welcomeMessage, terminal); - if (configShell.getCurrentConfig() != null) { - promptMessage = String.format("%s(%s)", - configShell.getCurrentConfig(), getHostFromUrl(serviceUrl)); - } else { - promptMessage = getHostFromUrl(serviceUrl); + if (prompt == null) { + final String welcomeMessage = + String.format("Welcome to Pulsar shell!\n %s: %s\n %s: %s\n\n" + + "Type %s to get started or try the autocompletion (TAB button).\n" + + "Type %s or %s to end the shell session.\n", + new AttributedStringBuilder().style(AttributedStyle.BOLD).append("Service URL") + .toAnsi(), serviceUrl, + new AttributedStringBuilder().style(AttributedStyle.BOLD).append("Admin URL").toAnsi(), + adminUrl, + new AttributedStringBuilder().style(AttributedStyle.BOLD).append("help").toAnsi(), + new AttributedStringBuilder().style(AttributedStyle.BOLD).append("exit").toAnsi(), + new AttributedStringBuilder().style(AttributedStyle.BOLD).append("quit").toAnsi()); + output(welcomeMessage, terminal); + + if (configShell.getCurrentConfig() != null) { + promptMessage = String.format("%s(%s)", + configShell.getCurrentConfig(), getHostFromUrl(serviceUrl)); + } else { + promptMessage = getHostFromUrl(serviceUrl); + } + prompt = createPrompt(promptMessage); } - prompt = createPrompt(promptMessage); return new InteractiveLineReader() { @Override public String readLine() { @@ -450,19 +455,19 @@ public List readCommand() { output(String.format("Exiting from %s shell mode", shellMode.command), terminal); prompt = createPrompt(promptMessage); shellMode = ShellMode.DEFAULT; + reader = readerBuilder.apply(registerProviders(properties)); continue; } exit(0); return; } - if (shellMode != ShellMode.DEFAULT) { - words.add(0, shellMode.command); - line = shellMode.command + " " + line; - } else { + if (shellMode == ShellMode.DEFAULT) { ShellMode newShellMode = ShellMode.valueOfCommand(line.toLowerCase(Locale.ROOT)); if (newShellMode != null) { shellMode = newShellMode; prompt = createPrompt(promptMessage + " " + shellMode.command); + updateShellCommander(properties); + reader = readerBuilder.apply(providersMap); continue; } } @@ -471,10 +476,12 @@ public List readCommand() { continue; } - final ShellCommandsProvider pulsarShellCommandsProvider = getProviderFromArgs(shellCommander, words); - if (pulsarShellCommandsProvider == null) { - shellCommander.usage(System.out); - continue; + if (shellMode == ShellMode.DEFAULT) { + final ShellCommandsProvider pulsarShellCommandsProvider = getProviderFromArgs(shellCommander, words); + if (pulsarShellCommandsProvider == null) { + shellCommander.usage(System.out); + continue; + } } boolean commandOk = false; try { @@ -605,13 +612,40 @@ private Map registerProviders(Properties properti registerProvider(createClientShell(properties), shellCommander, providerMap); registerProvider(configShell, shellCommander, providerMap); + updateSystemRegistry(); + + return providerMap; + } + + private void updateShellCommander(Properties properties) throws Exception { + ShellCommandsProvider shellCommandsProvider = createShellFromMode(properties, shellMode); + shellCommander = shellCommandsProvider.getCommander(); + updateSystemRegistry(); + } + + private void updateSystemRegistry() { Supplier workDir = () -> Paths.get(DEFAULT_PULSAR_SHELL_ROOT_DIRECTORY); PicocliCommands picocliCommands = new PicocliCommands(shellCommander); systemRegistry = new SystemRegistryImpl(parser, terminal, workDir, null); systemRegistry.setCommandRegistries(picocliCommands); systemRegistry.register("help", picocliCommands); + } - return providerMap; + protected ShellCommandsProvider createShellFromMode(Properties properties, ShellMode shellMode) throws Exception { + switch (shellMode) { + case ADMIN -> { + return createAdminShell(properties); + } + case CLIENT -> { + return createClientShell(properties); + } + case CONFIG -> { + return configShell; + } + default -> { + return shellCommander.getCommand(); + } + } } protected AdminShell createAdminShell(Properties properties) throws Exception { From d9084e7b92937c829729a6e86309567f44d4d386 Mon Sep 17 00:00:00 2001 From: Malla Sandeep Date: Thu, 12 Sep 2024 11:53:48 +0530 Subject: [PATCH 6/6] removed config from shell modes. --- .../src/main/java/org/apache/pulsar/shell/PulsarShell.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java b/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java index 86e7b511bf8a2..5007b9df5d1cf 100644 --- a/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java +++ b/pulsar-client-tools/src/main/java/org/apache/pulsar/shell/PulsarShell.java @@ -135,7 +135,6 @@ enum ExecState { enum ShellMode { ADMIN("admin"), CLIENT("client"), - CONFIG("config"), DEFAULT(""); private static final Map COMMAND_MAP = new HashMap<>(); @@ -639,9 +638,6 @@ protected ShellCommandsProvider createShellFromMode(Properties properties, Shell case CLIENT -> { return createClientShell(properties); } - case CONFIG -> { - return configShell; - } default -> { return shellCommander.getCommand(); }