Skip to content

Commit

Permalink
[improve][cli] Pulsar shell: add command to set/get property of a con…
Browse files Browse the repository at this point in the history
…fig (#17651)

(cherry picked from commit 4ec1009)
  • Loading branch information
nicoloboschi committed Nov 28, 2022
1 parent fc68304 commit 4d0646b
Show file tree
Hide file tree
Showing 6 changed files with 290 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import lombok.Getter;
import lombok.SneakyThrows;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.pulsar.shell.config.ConfigStore;

/**
Expand Down Expand Up @@ -79,11 +80,12 @@ private interface RunnableWithResult {
private final ConfigStore configStore;
private final ObjectMapper writer = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
@Getter
private String currentConfig = DEFAULT_CONFIG;
private String currentConfig;

public ConfigShell(PulsarShell pulsarShell) {
public ConfigShell(PulsarShell pulsarShell, String currentConfig) {
this.configStore = pulsarShell.getConfigStore();
this.pulsarShell = pulsarShell;
this.currentConfig = currentConfig;
}

@Override
Expand Down Expand Up @@ -114,6 +116,8 @@ public void setupState(Properties properties) {
commands.put("delete", new CmdConfigDelete());
commands.put("use", new CmdConfigUse());
commands.put("view", new CmdConfigView());
commands.put("set-property", new CmdConfigSetProperty());
commands.put("get-property", new CmdConfigGetProperty());
commands.forEach((k, v) -> jcommander.addCommand(k, v));
}

Expand Down Expand Up @@ -336,18 +340,98 @@ public boolean run() {
return false;
}

configStore.putConfig(new ConfigStore.ConfigEntry(name, value));
if (currentConfig.equals(name)) {
final Properties properties = new Properties();
properties.load(new StringReader(value));
pulsarShell.reload(properties);
}
final ConfigStore.ConfigEntry entry = new ConfigStore.ConfigEntry(name, value);
configStore.putConfig(entry);
reloadIfCurrent(entry);
return true;
}



abstract boolean verifyCondition();
}

private void reloadIfCurrent(ConfigStore.ConfigEntry entry) throws Exception {
if (currentConfig.equals(entry.getName())) {
final Properties properties = new Properties();
properties.load(new StringReader(entry.getValue()));
pulsarShell.reload(properties);
}
}


@Parameters(commandDescription = "Set a configuration property by name")
private class CmdConfigSetProperty implements RunnableWithResult {

@Parameter(description = "Name of the config", required = true)
@JCommanderCompleter.ParameterCompleter(type = JCommanderCompleter.ParameterCompleter.Type.CONFIGS)
private String name;

@Parameter(names = {"-p", "--property"}, required = true, description = "Name of the property to update")
protected String propertyName;

@Parameter(names = {"-v", "--value"}, description = "New value for the property")
protected String propertyValue;

@Override
@SneakyThrows
public boolean run() {
if (StringUtils.isBlank(propertyName)) {
print("-p parameter is required");
return false;
}

if (propertyValue == null) {
print("-v parameter is required. you can pass an empty value to empty the property. (-v= )");
return false;
}


final ConfigStore.ConfigEntry config = configStore.getConfig(this.name);
if (config == null) {
print("Config " + name + " not found");
return false;
}
ConfigStore.setProperty(config, propertyName, propertyValue);
print("Property " + propertyName + " set for config " + name);
configStore.putConfig(config);
reloadIfCurrent(config);
return true;
}
}

@Parameters(commandDescription = "Get a configuration property by name")
private class CmdConfigGetProperty implements RunnableWithResult {

@Parameter(description = "Name of the config", required = true)
@JCommanderCompleter.ParameterCompleter(type = JCommanderCompleter.ParameterCompleter.Type.CONFIGS)
private String name;

@Parameter(names = {"-p", "--property"}, required = true, description = "Name of the property")
protected String propertyName;

@Override
@SneakyThrows
public boolean run() {
if (StringUtils.isBlank(propertyName)) {
print("-p parameter is required");
return false;
}

final ConfigStore.ConfigEntry config = configStore.getConfig(this.name);
if (config == null) {
print("Config " + name + " not found");
return false;
}
final String value = ConfigStore.getProperty(config, propertyName);
if (!StringUtils.isBlank(value)) {
print(value);
}
return true;
}
}



<T> void print(List<T> items) {
for (T item : items) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,9 @@ static final class MainOptions {
private final JCommander mainCommander;
private final MainOptions mainOptions;
private JCommander shellCommander;
private final String[] args;
private Function<Map<String, ShellCommandsProvider>, InteractiveLineReader> readerBuilder;
private InteractiveLineReader reader;
private ConfigShell configShell;
private final ConfigShell configShell;

public PulsarShell(String args[]) throws IOException {
this(args, new Properties());
Expand Down Expand Up @@ -175,12 +174,14 @@ public PulsarShell(String args[], Properties props) throws IOException {
defaultConfig);

final ConfigStore.ConfigEntry lastUsed = configStore.getLastUsed();
String configName = ConfigStore.DEFAULT_CONFIG;
if (lastUsed != null) {
properties.load(new StringReader(lastUsed.getValue()));
configName = lastUsed.getName();
} else if (defaultConfig != null) {
properties.load(new StringReader(defaultConfig.getValue()));
}
this.args = args;
configShell = new ConfigShell(this, configName);
}

private static File computePulsarShellFile() {
Expand Down Expand Up @@ -266,7 +267,7 @@ public void run() throws Exception {
new AttributedStringBuilder().style(AttributedStyle.BOLD).append("quit").toAnsi());
output(welcomeMessage, terminal);
String promptMessage;
if (configShell != null && configShell.getCurrentConfig() != null) {
if (configShell.getCurrentConfig() != null) {
promptMessage = String.format("%s(%s)",
configShell.getCurrentConfig(), getHostFromUrl(serviceUrl));
} else {
Expand Down Expand Up @@ -567,9 +568,6 @@ private Map<String, ShellCommandsProvider> registerProviders(JCommander commande
final Map<String, ShellCommandsProvider> providerMap = new HashMap<>();
registerProvider(createAdminShell(properties), commander, providerMap);
registerProvider(createClientShell(properties), commander, providerMap);
if (configShell == null) {
configShell = new ConfigShell(this);
}
registerProvider(configShell, commander, providerMap);
return providerMap;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
package org.apache.pulsar.shell.config;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
Expand Down Expand Up @@ -50,4 +53,73 @@ class ConfigEntry {
void setLastUsed(String name) throws IOException;

ConfigEntry getLastUsed() throws IOException;

static void cleanupValue(ConfigEntry entry) {
StringBuilder builder = new StringBuilder();
try (Scanner scanner = new Scanner(entry.getValue());) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (line.isBlank() || line.startsWith("#")) {
continue;
}
builder.append(line);
builder.append(System.lineSeparator());
}
}
entry.setValue(builder.toString());
}

static void setProperty(ConfigEntry entry, String propertyName, String propertyValue) {
Set<String> keys = new HashSet<>();
StringBuilder builder = new StringBuilder();
try (Scanner scanner = new Scanner(entry.getValue());) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (line.isBlank() || line.startsWith("#")) {
continue;
}
final String[] split = line.split("=", 2);
if (split.length > 0) {
final String property = split[0];
if (!keys.add(property)) {
continue;
}
if (property.equals(propertyName)) {
line = property + "=" + propertyValue;
}
}
builder.append(line);
builder.append(System.lineSeparator());
}
if (!keys.contains(propertyName)) {
builder.append(propertyName + "=" + propertyValue);
builder.append(System.lineSeparator());
}
}
entry.setValue(builder.toString());
}

static String getProperty(ConfigEntry entry, String propertyName) {
try (Scanner scanner = new Scanner(entry.getValue());) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (line.isBlank() || line.startsWith("#")) {
continue;
}
final String[] split = line.split("=", 2);
if (split.length > 0) {
final String property = split[0];
if (property.equals(propertyName)) {
if (split.length > 1) {
return split[1];
}
return null;
}
}
}
}
return null;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Scanner;
import lombok.Data;
import lombok.NoArgsConstructor;

Expand Down Expand Up @@ -61,7 +60,7 @@ public FileConfigStore(File file, ConfigEntry defaultConfig) throws IOException
}
if (defaultConfig != null) {
this.defaultConfig = new ConfigEntry(defaultConfig.getName(), defaultConfig.getValue());
cleanupValue(this.defaultConfig);
ConfigStore.cleanupValue(this.defaultConfig);
} else {
this.defaultConfig = null;
}
Expand All @@ -88,26 +87,11 @@ public void putConfig(ConfigEntry entry) throws IOException {
if (DEFAULT_CONFIG.equals(entry.getName())) {
throw new IllegalArgumentException("'" + DEFAULT_CONFIG + "' can't be modified.");
}
cleanupValue(entry);
ConfigStore.cleanupValue(entry);
fileConfig.configs.put(entry.getName(), entry);
write();
}

private static void cleanupValue(ConfigEntry entry) {
StringBuilder builder = new StringBuilder();
try (Scanner scanner = new Scanner(entry.getValue());) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (line.startsWith("#")) {
continue;
}
builder.append(line);
builder.append(System.lineSeparator());
}
}
entry.setValue(builder.toString());
}

@Override
public ConfigEntry getConfig(String name) {
if (DEFAULT_CONFIG.equals(name)) {
Expand Down
Loading

0 comments on commit 4d0646b

Please sign in to comment.