Skip to content

Commit

Permalink
Add:
Browse files Browse the repository at this point in the history
- "--user-property"
- "--output-to-file"
- "--base64"
- "--json-output"
- "--show-topics"

Deprecate:
- "-up", "--userProperty"
- "-of", "--outputToFile"
- "-b64"
- "--jsonOutput"
- "--showTopics"
  • Loading branch information
LukasBrand committed Oct 2, 2024
1 parent 4285da1 commit e4d4260
Show file tree
Hide file tree
Showing 7 changed files with 588 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import picocli.CommandLine;

import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Callable;

Expand All @@ -41,6 +43,7 @@
public class SubscribeCommand implements Callable<Integer> {

private static final int IDLE_TIME = 5000;
private final @NotNull List<String> deprecationWarnings = new ArrayList<>();
private final @NotNull MqttClientExecutor mqttClientExecutor;
private @Nullable MqttClient subscribeClient;

Expand All @@ -64,7 +67,7 @@ private void printToSTDOUT(final boolean printToSTDOUT) {
private final @NotNull ConnectOptions connectOptions = new ConnectOptions();

@CommandLine.Mixin
private final @NotNull SubscribeOptions subscribeOptions = new SubscribeOptions();
private final @NotNull SubscribeOptions subscribeOptions = new SubscribeOptions(deprecationWarnings);

@CommandLine.Mixin
private final @NotNull DebugOptions debugOptions = new DebugOptions();
Expand All @@ -90,6 +93,8 @@ public SubscribeCommand(final @NotNull MqttClientExecutor mqttClientExecutor) {

Logger.trace("Command {}", this);

LoggerUtils.logDeprecatedOptions(deprecationWarnings);

connectOptions.setDefaultOptions();
connectOptions.logUnusedOptions();
subscribeOptions.setDefaultOptions();
Expand Down
166 changes: 150 additions & 16 deletions src/main/java/com/hivemq/cli/commands/options/SubscribeOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,17 @@
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

public class SubscribeOptions {

@SuppressWarnings({"NotNullFieldNotInitialized", "unused"})
@CommandLine.Spec
private @NotNull CommandLine.Model.CommandSpec spec;

private final @NotNull List<String> deprecationWarnings;

@SuppressWarnings({"NotNullFieldNotInitialized", "unused"}) //will be initialized via required
@CommandLine.Option(names = {"-t", "--topic"}, required = true, description = "The topics to subscribe to")
private @NotNull String @NotNull [] topics;
Expand All @@ -48,37 +55,164 @@ public class SubscribeOptions {
description = "Quality of service for the corresponding topics (default for all: 2)")
private @NotNull MqttQos @NotNull [] qos;

private @NotNull Mqtt5UserProperty @Nullable [] userProperties = null;
private boolean userPropertiesFromOption = false;
private boolean userPropertiesFromLegacyOption = false;

@SuppressWarnings("unused")
@CommandLine.Option(names = {"-up", "--userProperty"},
@CommandLine.Option(names = {"--user-property"},
converter = Mqtt5UserPropertyConverter.class,
description = "A user property of the subscribe message")
private @Nullable Mqtt5UserProperty @Nullable [] userProperties;
private void userProperties(final @NotNull Mqtt5UserProperty @NotNull [] userProperties) {
if (userPropertiesFromLegacyOption) {
throw new CommandLine.ParameterException(spec.commandLine(),
"A mix of the user properties legacy options \"-up\" or \"--userProperty\" and the current \"--user-property\" is used. Please only use \"--user-property\" as the legacy options will be removed in a future version.");
}
userPropertiesFromOption = true;
this.userProperties = userProperties;
}

@SuppressWarnings("unused")
@CommandLine.Option(names = {"-of", "--outputToFile"},
@Deprecated(since = "4.34.0", forRemoval = true)
@CommandLine.Option(names = {"-up", "--userProperty"},
hidden = true,
converter = Mqtt5UserPropertyConverter.class,
description = "Options \"-up\" and \"--userProperty\" are legacy, please use \"--user-property\". They will be removed in a future version.")
private void userPropertiesLegacy(final @NotNull Mqtt5UserProperty @NotNull [] userPropertiesLegacy) {
//only show message once as this method is executed multiple times
if (!userPropertiesFromLegacyOption) {
deprecationWarnings.add(
"Options \"-up\" and \"--userProperty\" are legacy, please use \"--user-property\". They will be removed in a future version.");
}

if (userPropertiesFromOption) {
throw new CommandLine.ParameterException(spec.commandLine(),
"A mix of the user properties legacy options \"-up\" or \"--userProperty\" and the current \"--user-property\" is used. Please only use \"--user-property\" as the legacy options will be removed in a future version.");
}
userPropertiesFromLegacyOption = true;
userProperties = userPropertiesLegacy;
}

private @Nullable File outputFile = null;

@SuppressWarnings("unused")
@CommandLine.Option(names = {"--output-to-file"},
description = "A file to which the received publish messages will be written")
private @Nullable File outputFile;
private void outputFile(final @NotNull File outputFile) {
if (this.outputFile != null) {
throw new CommandLine.ParameterException(spec.commandLine(),
"A mix of the output file legacy options \"-of\" or \"--outputToFile\" and the current \"--output-to-file\" is used. Please only use \"--output-to-file\" as the legacy options will be removed in a future version.");
}
this.outputFile = outputFile;
}

@SuppressWarnings("unused")
@Deprecated(since = "4.34.0", forRemoval = true)
@CommandLine.Option(names = {"-of", "--outputToFile"},
hidden = true,
description = "Options \"-of\" and \"--outputToFile\" are legacy, please use \"--output-to-file\". They will be removed in a future version")
private void outputFileLegacy(final @NotNull File outputFileLegacy) {
deprecationWarnings.add(
"Options \"-of\" and \"--outputToFile\" are legacy, please use \"--output-to-file\". They will be removed in a future version.");

if (this.outputFile != null) {
throw new CommandLine.ParameterException(spec.commandLine(),
"A mix of the output file legacy options \"-of\" or \"--outputToFile\" and the current \"--output-to-file\" is used. Please only use \"--output-to-file\" as the legacy options will be removed in a future version.");
}
this.outputFile = outputFileLegacy;
}

private boolean isPayloadEncodeToBase64 = false;

@SuppressWarnings("unused")
@CommandLine.Option(names = {"-b64", "--base64"},
@CommandLine.Option(names = {"--base64"},
description = "Specify the encoding of the received messages as Base64 (default: false)")
private boolean base64;
private void isMessageBase64Encoded(final boolean base64) {
if (isPayloadEncodeToBase64) {
throw new CommandLine.ParameterException(spec.commandLine(),
"A mix of the base64 legacy options \"-b64\" and the current \"--base64\" is used. Please only use \"--base64\" as the legacy options will be removed in a future version.");
}
isPayloadEncodeToBase64 = base64;
}

@SuppressWarnings("unused")
@Deprecated(since = "4.34.0", forRemoval = true)
@CommandLine.Option(names = {"-b64"},
hidden = true,
description = "Option \"-b64\" is legacy, please use \"--base64\". It will be removed in a future version")
private void isMessageBase64EncodedLegacy(final boolean base64Legacy) {
deprecationWarnings.add(
"Option \"-b64\" is legacy, please use \"--base64\". It will be removed in a future version.");

if (isPayloadEncodeToBase64) {
throw new CommandLine.ParameterException(spec.commandLine(),
"A mix of the base64 legacy options \"-b64\" and the current \"--base64\" is used. Please only use \"--base64\" as the legacy options will be removed in a future version.");
}
isPayloadEncodeToBase64 = base64Legacy;
}

private boolean jsonOutput = false;

@SuppressWarnings("unused")
@CommandLine.Option(names = {"-J", "--jsonOutput"},
defaultValue = "false",
@CommandLine.Option(names = {"-J", "--json-output"},
description = "Print the received publishes in pretty JSON format")
private boolean jsonOutput;
private void jsonOutput(final boolean jsonOutput) {
if (this.jsonOutput) {
throw new CommandLine.ParameterException(spec.commandLine(),
"A mix of the json output legacy options \"--jsonOutput\" and the current \"-J\" or \"--json-output\" is used. Please only use \"-J\" or \"--json-output\" as the legacy options will be removed in a future version.");
}
this.jsonOutput = jsonOutput;
}

@SuppressWarnings("unused")
@Deprecated(since = "4.34.0", forRemoval = true)
@CommandLine.Option(names = {"--jsonOutput"},
hidden = true,
description = "Option \"--jsonOutput\" is legacy, please use \"--json-output\". It will be removed in a future version")
private void jsonOutputLegacy(final boolean jsonOutputLegacy) {
deprecationWarnings.add(
"Option \"--jsonOutput\" is legacy, please use \"--json-output\". It will be removed in a future version.");

if (jsonOutput) {
throw new CommandLine.ParameterException(spec.commandLine(),
"A mix of the json output legacy options \"--jsonOutput\" and the current \"-J\" or \"--json-output\" is used. Please only use \"-J\" or \"--json-output\" as the legacy options will be removed in a future version.");
}
jsonOutput = true;
}

private boolean showTopics = false;

@SuppressWarnings("unused")
@CommandLine.Option(names = {"-T", "--showTopics"},
defaultValue = "false",
@CommandLine.Option(names = {"-T", "--show-topics"},
description = "Prepend the specific topic name to the received publish")
private boolean showTopics;
private void showTopics(final boolean showTopics) {
if (this.showTopics) {
throw new CommandLine.ParameterException(spec.commandLine(),
"A mix of the show topics legacy options \"--showTopics\" and the current \"-T\" or \"--show-topics\" is used. Please only use \"-T\" or \"--show-topics\" as the legacy options will be removed in a future version.");
}
this.showTopics = showTopics;
}

@SuppressWarnings("unused")
@Deprecated(since = "4.34.0", forRemoval = true)
@CommandLine.Option(names = {"--showTopics"},
hidden = true,
description = "Option \"--showTopics\" is legacy, please use \"-T\" or \"--show-topics\". It will be removed in a future version")
private void showTopicsLegacy(final boolean showTopicsLegacy) {
deprecationWarnings.add(
"Option \"--showTopics\" is legacy, please use \"-T\" or \"--show-topics\". It will be removed in a future version.");

if (this.showTopics) {
throw new CommandLine.ParameterException(spec.commandLine(),
"A mix of the show topics legacy options \"--showTopics\" and the current \"-T\" or \"--show-topics\" is used. Please only use \"-T\" or \"--show-topics\" as the legacy options will be removed in a future version.");
}
showTopics = true;
}

private boolean printToSTDOUT = false;

public SubscribeOptions() {
public SubscribeOptions(final @NotNull List<String> deprecationWarnings) {
this.deprecationWarnings = deprecationWarnings;
setDefaultOptions();
}

Expand All @@ -98,8 +232,8 @@ public boolean isPrintToSTDOUT() {
return printToSTDOUT;
}

public boolean isBase64() {
return base64;
public boolean isPayloadEncodeToBase64() {
return isPayloadEncodeToBase64;
}

public boolean isJsonOutput() {
Expand Down Expand Up @@ -181,7 +315,7 @@ public void setDefaultOptions() {
", printToSTDOUT=" +
printToSTDOUT +
", base64=" +
base64 +
isPayloadEncodeToBase64 +
", jsonOutput=" +
jsonOutput +
", showTopics=" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import picocli.CommandLine;

import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Scanner;
import java.util.concurrent.Callable;
Expand All @@ -40,6 +42,8 @@ public class ContextSubscribeCommand extends ShellContextCommand implements Call

private static final int IDLE_TIME = 1000;

private final @NotNull List<String> deprecationWarnings = new ArrayList<>();

@SuppressWarnings("unused")
@CommandLine.Option(names = {"-s", "--stay"},
defaultValue = "false",
Expand All @@ -55,7 +59,7 @@ private void printToSTDOUT(final boolean printToSTDOUT) {
}

@CommandLine.Mixin
private final @NotNull SubscribeOptions subscribeOptions = new SubscribeOptions();
private final @NotNull SubscribeOptions subscribeOptions = new SubscribeOptions(deprecationWarnings);

@Inject
public ContextSubscribeCommand(final @NotNull MqttClientExecutor mqttClientExecutor) {
Expand All @@ -66,6 +70,8 @@ public ContextSubscribeCommand(final @NotNull MqttClientExecutor mqttClientExecu
public @NotNull Integer call() {
Logger.trace("Command {}", this);

LoggerUtils.logDeprecatedOptions(deprecationWarnings);

if (contextClient == null) {
Logger.error("The client to subscribe with does not exist");
return 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class SubscribeMqtt3PublishCallback implements Consumer<Mqtt3Publish> {
SubscribeMqtt3PublishCallback(final @NotNull SubscribeOptions subscribeOptions, final @NotNull Mqtt3Client client) {
printToStdout = subscribeOptions.isPrintToSTDOUT();
outputFile = subscribeOptions.getOutputFile();
isBase64 = subscribeOptions.isBase64();
isBase64 = subscribeOptions.isPayloadEncodeToBase64();
isJsonOutput = subscribeOptions.isJsonOutput();
showTopics = subscribeOptions.isShowTopics();
this.client = client;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class SubscribeMqtt5PublishCallback implements Consumer<Mqtt5Publish> {
SubscribeMqtt5PublishCallback(final @NotNull SubscribeOptions subscribeOptions, final @NotNull Mqtt5Client client) {
printToStdout = subscribeOptions.isPrintToSTDOUT();
outputFile = subscribeOptions.getOutputFile();
isBase64 = subscribeOptions.isBase64();
isBase64 = subscribeOptions.isPayloadEncodeToBase64();
isJsonOutput = subscribeOptions.isJsonOutput();
showTopics = subscribeOptions.isShowTopics();
this.client = client;
Expand Down
20 changes: 17 additions & 3 deletions src/main/java/com/hivemq/cli/utils/LoggerUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
Expand All @@ -56,7 +57,7 @@ public static void useDefaultLogging(final @Nullable Map<String, String> extende

// TinyLog configuration
// File Writer (creates logfiles under .mqtt-cli/logs folder)
final Map<String, String> configurationMap = new HashMap<String, String>() {{
final Map<String, String> configurationMap = new HashMap<>() {{
put("writer", "file");
put("writer.format", logfileFormatPattern);
put("writer.file", logfilePath.toString());
Expand All @@ -73,7 +74,7 @@ public static void useDefaultLogging(final @Nullable Map<String, String> extende

public static void setupConsoleLogging(final boolean logToLogfile, final @NotNull String logLevel) {
// TinyLog configuration
final Map<String, String> configurationMap = new HashMap<String, String>() {{
final Map<String, String> configurationMap = new HashMap<>() {{
put("writer1", "console");
if (logLevel.equals("debug") || logLevel.equals("trace")) {
put("writer1.format", "{message}");
Expand All @@ -94,7 +95,7 @@ public static void turnOffConsoleLogging(final boolean logToLogfile) {
if (logToLogfile) {
LoggerUtils.useDefaultLogging();
} else {
final Map<String, String> configurationMap = new HashMap<String, String>() {{
final Map<String, String> configurationMap = new HashMap<>() {{
put("writer.level", "off");
}};
Configuration.replace(configurationMap);
Expand Down Expand Up @@ -140,4 +141,17 @@ public static void logShellError(final @NotNull String message, final @NotNull E
Logger.error(exception, "{}. Use 'mqtt sh -l' to see more detailed information in the logfile.", message);
}
}

public static void logDeprecatedOptions(final @NotNull List<String> deprecationWarnings) {
if (!deprecationWarnings.isEmpty()) {
if (deprecationWarnings.size() == 1) {
Logger.warn(deprecationWarnings.get(0));
} else {
Logger.warn("There are deprecated options used in this command:");
for (final String deprecatedWarning : deprecationWarnings) {
Logger.warn(" - " + deprecatedWarning);
}
}
}
}
}
Loading

0 comments on commit e4d4260

Please sign in to comment.