Skip to content

Commit cd86b31

Browse files
authored
Merge pull request #462 from hivemq/feature/deprecate-bad-subscribe-options
Deprecate bad subscription options and add replacements
2 parents 7b293c9 + 399fe1f commit cd86b31

File tree

8 files changed

+597
-33
lines changed

8 files changed

+597
-33
lines changed
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
| Option | Long Version | Explanation | Default |
2-
|--------|------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|
3-
| `-t` | `--topic` | The MQTT topic the client will subscribe to. | |
4-
| `-q` | `--qos` | Define the quality of service level. If only one QoS is specified it will be used for all topics.<br> You can define a specific QoS level for every topic. The corresponding QoS levels will be matched in order to the given topics. | `0` |
5-
| `-of` | `--outputToFile` | Append the received publish messages to a file. Creates the file if it does not exist. | |
6-
| `-b64` | `--base64` | Whether the received publish messages will be base64 encoded. | `false` |
7-
| `-J` | `--jsonOutput` | Print the received publishes in pretty JSON format. | `false` |
8-
| `-T` | `--showTopics` | Prepend the specific topic name to the received publish. | `false` |
9-
| `-up` | `--userProperty` | A user property of the subscribe message. | |
1+
| Option | Long Version | Explanation | Default |
2+
|--------|--------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|
3+
| `-t` | `--topic` | The MQTT topic the client will subscribe to. | |
4+
| `-q` | `--qos` | Define the quality of service level. If only one QoS is specified it will be used for all topics.<br> You can define a specific QoS level for every topic. The corresponding QoS levels will be matched in order to the given topics. | `0` |
5+
| | `--output-to-file` | Append the received publish messages to a file. Creates the file if it does not exist. | |
6+
| | `--base64` | Whether the received publish messages will be base64 encoded. | `false` |
7+
| `-J` | `--json-output` | Print the received publishes in pretty JSON format. | `false` |
8+
| `-T` | `--show-topics` | Prepend the specific topic name to the received publish. | `false` |
9+
| | `--user-property` | A user property of the subscribe message. | |

src/main/java/com/hivemq/cli/commands/cli/SubscribeCommand.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import picocli.CommandLine;
3232

3333
import javax.inject.Inject;
34+
import java.util.ArrayList;
35+
import java.util.List;
3436
import java.util.Objects;
3537
import java.util.concurrent.Callable;
3638

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

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

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

6669
@CommandLine.Mixin
67-
private final @NotNull SubscribeOptions subscribeOptions = new SubscribeOptions();
70+
private final @NotNull SubscribeOptions subscribeOptions = new SubscribeOptions(deprecationWarnings);
6871

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

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

96+
LoggerUtils.logDeprecatedOptions(deprecationWarnings);
97+
9398
connectOptions.setDefaultOptions();
9499
connectOptions.logUnusedOptions();
95100
subscribeOptions.setDefaultOptions();

src/main/java/com/hivemq/cli/commands/options/SubscribeOptions.java

Lines changed: 150 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,17 @@
3333
import java.io.File;
3434
import java.io.IOException;
3535
import java.util.Arrays;
36+
import java.util.List;
3637
import java.util.Objects;
3738

3839
public class SubscribeOptions {
3940

41+
@SuppressWarnings({"NotNullFieldNotInitialized", "unused"})
42+
@CommandLine.Spec
43+
private @NotNull CommandLine.Model.CommandSpec spec;
44+
45+
private final @NotNull List<String> deprecationWarnings;
46+
4047
@SuppressWarnings({"NotNullFieldNotInitialized", "unused"}) //will be initialized via required
4148
@CommandLine.Option(names = {"-t", "--topic"}, required = true, description = "The topics to subscribe to")
4249
private @NotNull String @NotNull [] topics;
@@ -48,37 +55,164 @@ public class SubscribeOptions {
4855
description = "Quality of service for the corresponding topics (default for all: 2)")
4956
private @NotNull MqttQos @NotNull [] qos;
5057

58+
private @NotNull Mqtt5UserProperty @Nullable [] userProperties = null;
59+
private boolean userPropertiesFromOption = false;
60+
private boolean userPropertiesFromLegacyOption = false;
61+
5162
@SuppressWarnings("unused")
52-
@CommandLine.Option(names = {"-up", "--userProperty"},
63+
@CommandLine.Option(names = {"--user-property"},
5364
converter = Mqtt5UserPropertyConverter.class,
5465
description = "A user property of the subscribe message")
55-
private @Nullable Mqtt5UserProperty @Nullable [] userProperties;
66+
private void userProperties(final @NotNull Mqtt5UserProperty @NotNull [] userProperties) {
67+
if (userPropertiesFromLegacyOption) {
68+
throw new CommandLine.ParameterException(spec.commandLine(),
69+
"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.");
70+
}
71+
userPropertiesFromOption = true;
72+
this.userProperties = userProperties;
73+
}
5674

5775
@SuppressWarnings("unused")
58-
@CommandLine.Option(names = {"-of", "--outputToFile"},
76+
@Deprecated(since = "4.34.0", forRemoval = true)
77+
@CommandLine.Option(names = {"-up", "--userProperty"},
78+
hidden = true,
79+
converter = Mqtt5UserPropertyConverter.class,
80+
description = "Options \"-up\" and \"--userProperty\" are legacy, please use \"--user-property\". Legacy options will be removed in a future version.")
81+
private void userPropertiesLegacy(final @NotNull Mqtt5UserProperty @NotNull [] userPropertiesLegacy) {
82+
//only show message once as this method is executed multiple times
83+
if (!userPropertiesFromLegacyOption) {
84+
deprecationWarnings.add(
85+
"Options \"-up\" and \"--userProperty\" are legacy, please use \"--user-property\". Legacy options will be removed in a future version.");
86+
}
87+
88+
if (userPropertiesFromOption) {
89+
throw new CommandLine.ParameterException(spec.commandLine(),
90+
"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.");
91+
}
92+
userPropertiesFromLegacyOption = true;
93+
userProperties = userPropertiesLegacy;
94+
}
95+
96+
private @Nullable File outputFile = null;
97+
98+
@SuppressWarnings("unused")
99+
@CommandLine.Option(names = {"--output-to-file"},
59100
description = "A file to which the received publish messages will be written")
60-
private @Nullable File outputFile;
101+
private void outputFile(final @NotNull File outputFile) {
102+
if (this.outputFile != null) {
103+
throw new CommandLine.ParameterException(spec.commandLine(),
104+
"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.");
105+
}
106+
this.outputFile = outputFile;
107+
}
108+
109+
@SuppressWarnings("unused")
110+
@Deprecated(since = "4.34.0", forRemoval = true)
111+
@CommandLine.Option(names = {"-of", "--outputToFile"},
112+
hidden = true,
113+
description = "Options \"-of\" and \"--outputToFile\" are legacy, please use \"--output-to-file\". Legacy options will be removed in a future version")
114+
private void outputFileLegacy(final @NotNull File outputFileLegacy) {
115+
deprecationWarnings.add(
116+
"Options \"-of\" and \"--outputToFile\" are legacy, please use \"--output-to-file\". Legacy options will be removed in a future version.");
117+
118+
if (this.outputFile != null) {
119+
throw new CommandLine.ParameterException(spec.commandLine(),
120+
"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.");
121+
}
122+
this.outputFile = outputFileLegacy;
123+
}
124+
125+
private boolean isEncodePayloadInBase64 = false;
61126

62127
@SuppressWarnings("unused")
63-
@CommandLine.Option(names = {"-b64", "--base64"},
128+
@CommandLine.Option(names = {"--base64"},
64129
description = "Specify the encoding of the received messages as Base64 (default: false)")
65-
private boolean base64;
130+
private void isMessageBase64Encoded(final boolean base64) {
131+
if (isEncodePayloadInBase64) {
132+
throw new CommandLine.ParameterException(spec.commandLine(),
133+
"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.");
134+
}
135+
isEncodePayloadInBase64 = base64;
136+
}
137+
138+
@SuppressWarnings("unused")
139+
@Deprecated(since = "4.34.0", forRemoval = true)
140+
@CommandLine.Option(names = {"-b64"},
141+
hidden = true,
142+
description = "Option \"-b64\" is legacy, please use \"--base64\". The legacy option will be removed in a future version")
143+
private void isMessageBase64EncodedLegacy(final boolean base64Legacy) {
144+
deprecationWarnings.add(
145+
"Option \"-b64\" is legacy, please use \"--base64\". The legacy option will be removed in a future version.");
146+
147+
if (isEncodePayloadInBase64) {
148+
throw new CommandLine.ParameterException(spec.commandLine(),
149+
"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.");
150+
}
151+
isEncodePayloadInBase64 = base64Legacy;
152+
}
153+
154+
private boolean jsonOutput = false;
66155

67156
@SuppressWarnings("unused")
68-
@CommandLine.Option(names = {"-J", "--jsonOutput"},
69-
defaultValue = "false",
157+
@CommandLine.Option(names = {"-J", "--json-output"},
70158
description = "Print the received publishes in pretty JSON format")
71-
private boolean jsonOutput;
159+
private void jsonOutput(final boolean jsonOutput) {
160+
if (this.jsonOutput) {
161+
throw new CommandLine.ParameterException(spec.commandLine(),
162+
"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.");
163+
}
164+
this.jsonOutput = jsonOutput;
165+
}
166+
167+
@SuppressWarnings("unused")
168+
@Deprecated(since = "4.34.0", forRemoval = true)
169+
@CommandLine.Option(names = {"--jsonOutput"},
170+
hidden = true,
171+
description = "Option \"--jsonOutput\" is legacy, please use \"--json-output\". The legacy option will be removed in a future version")
172+
private void jsonOutputLegacy(final boolean jsonOutputLegacy) {
173+
deprecationWarnings.add(
174+
"Option \"--jsonOutput\" is legacy, please use \"--json-output\". The legacy option will be removed in a future version.");
175+
176+
if (jsonOutput) {
177+
throw new CommandLine.ParameterException(spec.commandLine(),
178+
"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.");
179+
}
180+
jsonOutput = true;
181+
}
182+
183+
private boolean showTopics = false;
72184

73185
@SuppressWarnings("unused")
74-
@CommandLine.Option(names = {"-T", "--showTopics"},
75-
defaultValue = "false",
186+
@CommandLine.Option(names = {"-T", "--show-topics"},
76187
description = "Prepend the specific topic name to the received publish")
77-
private boolean showTopics;
188+
private void showTopics(final boolean showTopics) {
189+
if (this.showTopics) {
190+
throw new CommandLine.ParameterException(spec.commandLine(),
191+
"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.");
192+
}
193+
this.showTopics = showTopics;
194+
}
195+
196+
@SuppressWarnings("unused")
197+
@Deprecated(since = "4.34.0", forRemoval = true)
198+
@CommandLine.Option(names = {"--showTopics"},
199+
hidden = true,
200+
description = "Option \"--showTopics\" is legacy, please use \"-T\" or \"--show-topics\". The legacy option will be removed in a future version")
201+
private void showTopicsLegacy(final boolean showTopicsLegacy) {
202+
deprecationWarnings.add(
203+
"Option \"--showTopics\" is legacy, please use \"-T\" or \"--show-topics\". The legacy option will be removed in a future version.");
204+
205+
if (this.showTopics) {
206+
throw new CommandLine.ParameterException(spec.commandLine(),
207+
"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.");
208+
}
209+
showTopics = true;
210+
}
78211

79212
private boolean printToSTDOUT = false;
80213

81-
public SubscribeOptions() {
214+
public SubscribeOptions(final @NotNull List<String> deprecationWarnings) {
215+
this.deprecationWarnings = deprecationWarnings;
82216
setDefaultOptions();
83217
}
84218

@@ -98,8 +232,8 @@ public boolean isPrintToSTDOUT() {
98232
return printToSTDOUT;
99233
}
100234

101-
public boolean isBase64() {
102-
return base64;
235+
public boolean isEncodePayloadInBase64() {
236+
return isEncodePayloadInBase64;
103237
}
104238

105239
public boolean isJsonOutput() {
@@ -180,8 +314,7 @@ public void setDefaultOptions() {
180314
outputFile +
181315
", printToSTDOUT=" +
182316
printToSTDOUT +
183-
", base64=" +
184-
base64 +
317+
", base64=" + isEncodePayloadInBase64 +
185318
", jsonOutput=" +
186319
jsonOutput +
187320
", showTopics=" +

src/main/java/com/hivemq/cli/commands/shell/ContextSubscribeCommand.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import picocli.CommandLine;
2626

2727
import javax.inject.Inject;
28+
import java.util.ArrayList;
29+
import java.util.List;
2830
import java.util.Objects;
2931
import java.util.Scanner;
3032
import java.util.concurrent.Callable;
@@ -40,6 +42,8 @@ public class ContextSubscribeCommand extends ShellContextCommand implements Call
4042

4143
private static final int IDLE_TIME = 1000;
4244

45+
private final @NotNull List<String> deprecationWarnings = new ArrayList<>();
46+
4347
@SuppressWarnings("unused")
4448
@CommandLine.Option(names = {"-s", "--stay"},
4549
defaultValue = "false",
@@ -55,7 +59,7 @@ private void printToSTDOUT(final boolean printToSTDOUT) {
5559
}
5660

5761
@CommandLine.Mixin
58-
private final @NotNull SubscribeOptions subscribeOptions = new SubscribeOptions();
62+
private final @NotNull SubscribeOptions subscribeOptions = new SubscribeOptions(deprecationWarnings);
5963

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

73+
LoggerUtils.logDeprecatedOptions(deprecationWarnings);
74+
6975
if (contextClient == null) {
7076
Logger.error("The client to subscribe with does not exist");
7177
return 1;

src/main/java/com/hivemq/cli/mqtt/SubscribeMqtt3PublishCallback.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public class SubscribeMqtt3PublishCallback implements Consumer<Mqtt3Publish> {
4242
SubscribeMqtt3PublishCallback(final @NotNull SubscribeOptions subscribeOptions, final @NotNull Mqtt3Client client) {
4343
printToStdout = subscribeOptions.isPrintToSTDOUT();
4444
outputFile = subscribeOptions.getOutputFile();
45-
isBase64 = subscribeOptions.isBase64();
45+
isBase64 = subscribeOptions.isEncodePayloadInBase64();
4646
isJsonOutput = subscribeOptions.isJsonOutput();
4747
showTopics = subscribeOptions.isShowTopics();
4848
this.client = client;

src/main/java/com/hivemq/cli/mqtt/SubscribeMqtt5PublishCallback.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public class SubscribeMqtt5PublishCallback implements Consumer<Mqtt5Publish> {
4242
SubscribeMqtt5PublishCallback(final @NotNull SubscribeOptions subscribeOptions, final @NotNull Mqtt5Client client) {
4343
printToStdout = subscribeOptions.isPrintToSTDOUT();
4444
outputFile = subscribeOptions.getOutputFile();
45-
isBase64 = subscribeOptions.isBase64();
45+
isBase64 = subscribeOptions.isEncodePayloadInBase64();
4646
isJsonOutput = subscribeOptions.isJsonOutput();
4747
showTopics = subscribeOptions.isShowTopics();
4848
this.client = client;

0 commit comments

Comments
 (0)