Skip to content

Commit 17f09de

Browse files
authored
Merge pull request #253 from rabbitmq/rabbitmq-perf-test-252-sni
Add -sni option
2 parents 774d72f + 3c2cafd commit 17f09de

File tree

6 files changed

+146
-65
lines changed

6 files changed

+146
-65
lines changed

src/main/java/com/rabbitmq/perf/BaseMetrics.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import java.util.ArrayList;
3131
import java.util.Collection;
3232

33-
import static com.rabbitmq.perf.PerfTest.strArg;
33+
import static com.rabbitmq.perf.Utils.strArg;
3434

3535
/**
3636
*

src/main/java/com/rabbitmq/perf/DatadogMetrics.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import java.util.Map;
3131

3232
import static com.rabbitmq.perf.PerfTest.hasOption;
33-
import static com.rabbitmq.perf.PerfTest.strArg;
33+
import static com.rabbitmq.perf.Utils.strArg;
3434
import static java.lang.Boolean.valueOf;
3535

3636
/**

src/main/java/com/rabbitmq/perf/PerfTest.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.util.function.Function;
3838

3939
import static com.rabbitmq.perf.OptionsUtils.forEach;
40+
import static com.rabbitmq.perf.Utils.strArg;
4041
import static java.lang.String.format;
4142
import static java.util.Arrays.asList;
4243
import static java.util.Collections.singletonList;
@@ -204,7 +205,8 @@ public static void main(String [] args, PerfTestOptions perfTestOptions) {
204205

205206
factory.setTopologyRecoveryEnabled(false);
206207

207-
RecoveryDelayHandler recoveryDelayHandler = Utils.getRecoveryDelayHandler(strArg(cmd, "cri", null));
208+
RecoveryDelayHandler recoveryDelayHandler = Utils.getRecoveryDelayHandler(
209+
strArg(cmd, "cri", null));
208210
if (recoveryDelayHandler != null) {
209211
factory.setRecoveryDelayHandler(recoveryDelayHandler);
210212
}
@@ -277,6 +279,11 @@ public static void main(String [] args, PerfTestOptions perfTestOptions) {
277279
shutdownService.wrap(() -> nioExecutor.shutdownNow());
278280
}
279281

282+
factory.setSocketConfigurator(Utils.socketConfigurator(cmd));
283+
if (factory.getNioParams() != null) {
284+
factory.getNioParams().setSslEngineConfigurator(Utils.sslEngineConfigurator(cmd));
285+
}
286+
280287
MulticastParams p = new MulticastParams();
281288
p.setAutoAck( autoAck);
282289
p.setAutoDelete( autoDelete);
@@ -650,15 +657,9 @@ public static Options getOptions() {
650657
+ "e.g. x-priority=10"));
651658
options.addOption(new Option("cri", "connection-recovery-interval", true, "connection recovery interval in seconds. Default is 5 seconds. "
652659
+ "Interval syntax, e.g. 30-60, is supported to specify an random interval between 2 values between each attempt."));
653-
return options;
654-
}
655660

656-
static String strArg(CommandLineProxy cmd, char opt, String def) {
657-
return cmd.getOptionValue(opt, def);
658-
}
659-
660-
static String strArg(CommandLineProxy cmd, String opt, String def) {
661-
return cmd.getOptionValue(opt, def);
661+
options.addOption(new Option("sni", "server-name-indication", true, "server names for Server Name Indication TLS parameter, separated by commas"));
662+
return options;
662663
}
663664

664665
static int intArg(CommandLineProxy cmd, char opt, int def) {

src/main/java/com/rabbitmq/perf/PrometheusMetrics.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
import java.io.IOException;
3535

3636
import static com.rabbitmq.perf.PerfTest.intArg;
37-
import static com.rabbitmq.perf.PerfTest.strArg;
37+
import static com.rabbitmq.perf.Utils.strArg;
3838

3939
/**
4040
*

src/main/java/com/rabbitmq/perf/Utils.java

Lines changed: 132 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -19,85 +19,165 @@
1919
import com.rabbitmq.client.Connection;
2020
import com.rabbitmq.client.ConnectionFactory;
2121
import com.rabbitmq.client.RecoveryDelayHandler;
22+
import com.rabbitmq.client.SocketConfigurator;
23+
import com.rabbitmq.client.SocketConfigurators;
24+
import com.rabbitmq.client.SslEngineConfigurator;
25+
import com.rabbitmq.client.SslEngineConfigurators;
2226
import com.rabbitmq.client.impl.recovery.AutorecoveringConnection;
23-
2427
import java.net.URISyntaxException;
2528
import java.security.KeyManagementException;
2629
import java.security.NoSuchAlgorithmException;
27-
import java.util.concurrent.*;
30+
import java.util.Arrays;
31+
import java.util.Collections;
32+
import java.util.List;
33+
import java.util.concurrent.ExecutionException;
34+
import java.util.concurrent.Future;
35+
import java.util.concurrent.ThreadLocalRandom;
36+
import java.util.concurrent.TimeUnit;
37+
import java.util.concurrent.TimeoutException;
2838
import java.util.regex.Matcher;
2939
import java.util.regex.Pattern;
40+
import java.util.stream.Collectors;
41+
import javax.net.ssl.SNIHostName;
42+
import javax.net.ssl.SNIServerName;
43+
import javax.net.ssl.SSLParameters;
44+
import javax.net.ssl.SSLSocket;
45+
import org.slf4j.Logger;
46+
import org.slf4j.LoggerFactory;
3047

3148
abstract class Utils {
3249

33-
private static final ConnectionFactory CF = new ConnectionFactory();
34-
35-
static boolean isRecoverable(Connection connection) {
36-
return connection instanceof AutorecoveringConnection;
37-
}
38-
39-
static synchronized Address extract(String uri) throws NoSuchAlgorithmException, KeyManagementException, URISyntaxException {
40-
CF.setUri(uri);
41-
return new Address(CF.getHost(), CF.getPort());
42-
}
43-
44-
/**
45-
* @param argument
46-
* @return
47-
* @since 2.11.0
48-
*/
49-
static RecoveryDelayHandler getRecoveryDelayHandler(String argument) {
50-
if (argument == null || argument.trim().isEmpty()) {
51-
return null;
52-
}
53-
argument = argument.trim();
54-
Pattern pattern = Pattern.compile("(\\d+)(-(\\d+))?");
55-
Matcher matcher = pattern.matcher(argument);
56-
if (!matcher.matches()) {
57-
throw new IllegalArgumentException("Incorrect argument for connection recovery interval. Must be e.g. 30 or 30-60.");
58-
}
59-
60-
RecoveryDelayHandler handler;
61-
final long delay = Long.parseLong(matcher.group(1)) * 1000;
62-
if (matcher.group(2) == null) {
63-
handler = recoveryAttempts -> delay;
64-
} else {
65-
final long maxInput = Long.parseLong(matcher.group(2).replace("-", "")) * 1000;
66-
if (maxInput <= delay) {
67-
throw new IllegalArgumentException("Wrong interval min-max values: " + argument);
68-
}
69-
final long maxDelay = maxInput + 1000;
70-
handler = recoveryAttempts -> ThreadLocalRandom.current().nextLong(delay, maxDelay);
71-
}
72-
return handler;
73-
}
74-
75-
static final Future<?> NO_OP_FUTURE = new Future<Object>() {
50+
static final Future<?> NO_OP_FUTURE =
51+
new Future<Object>() {
7652

7753
@Override
7854
public boolean cancel(boolean mayInterruptIfRunning) {
79-
return true;
55+
return true;
8056
}
8157

8258
@Override
8359
public boolean isCancelled() {
84-
return false;
60+
return false;
8561
}
8662

8763
@Override
8864
public boolean isDone() {
89-
return true;
65+
return true;
9066
}
9167

9268
@Override
9369
public Object get() throws InterruptedException, ExecutionException {
94-
return null;
70+
return null;
9571
}
9672

9773
@Override
98-
public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
99-
return null;
74+
public Object get(long timeout, TimeUnit unit)
75+
throws InterruptedException, ExecutionException, TimeoutException {
76+
return null;
10077
}
101-
};
78+
};
79+
private static final Logger LOGGER = LoggerFactory.getLogger(Utils.class);
80+
private static final ConnectionFactory CF = new ConnectionFactory();
81+
82+
static boolean isRecoverable(Connection connection) {
83+
return connection instanceof AutorecoveringConnection;
84+
}
85+
86+
static synchronized Address extract(String uri)
87+
throws NoSuchAlgorithmException, KeyManagementException, URISyntaxException {
88+
CF.setUri(uri);
89+
return new Address(CF.getHost(), CF.getPort());
90+
}
91+
92+
/**
93+
* @param argument
94+
* @return
95+
* @since 2.11.0
96+
*/
97+
static RecoveryDelayHandler getRecoveryDelayHandler(String argument) {
98+
if (argument == null || argument.trim().isEmpty()) {
99+
return null;
100+
}
101+
argument = argument.trim();
102+
Pattern pattern = Pattern.compile("(\\d+)(-(\\d+))?");
103+
Matcher matcher = pattern.matcher(argument);
104+
if (!matcher.matches()) {
105+
throw new IllegalArgumentException(
106+
"Incorrect argument for connection recovery interval. Must be e.g. 30 or 30-60.");
107+
}
108+
109+
RecoveryDelayHandler handler;
110+
final long delay = Long.parseLong(matcher.group(1)) * 1000;
111+
if (matcher.group(2) == null) {
112+
handler = recoveryAttempts -> delay;
113+
} else {
114+
final long maxInput = Long.parseLong(matcher.group(2).replace("-", "")) * 1000;
115+
if (maxInput <= delay) {
116+
throw new IllegalArgumentException("Wrong interval min-max values: " + argument);
117+
}
118+
final long maxDelay = maxInput + 1000;
119+
handler = recoveryAttempts -> ThreadLocalRandom.current().nextLong(delay, maxDelay);
120+
}
121+
return handler;
122+
}
123+
124+
static List<SNIServerName> sniServerNames(String argumentValue) {
125+
if (argumentValue != null && !argumentValue.trim().isEmpty()) {
126+
return Arrays.stream(argumentValue.split(","))
127+
.map(s -> s.trim())
128+
.map(s -> new SNIHostName(s))
129+
.collect(Collectors.toList());
130+
} else {
131+
return Collections.emptyList();
132+
}
133+
}
134+
135+
static SocketConfigurator socketConfigurator(CommandLineProxy cmd) {
136+
List<SNIServerName> serverNames = sniServerNames(strArg(cmd, "sni", null));
137+
if (serverNames.isEmpty()) {
138+
return SocketConfigurators.defaultConfigurator();
139+
} else {
140+
SocketConfigurator socketConfigurator =
141+
socket -> {
142+
if (socket instanceof SSLSocket) {
143+
SSLSocket sslSocket = (SSLSocket) socket;
144+
SSLParameters sslParameters =
145+
sslSocket.getSSLParameters() == null
146+
? new SSLParameters()
147+
: sslSocket.getSSLParameters();
148+
sslParameters.setServerNames(serverNames);
149+
sslSocket.setSSLParameters(sslParameters);
150+
} else {
151+
LOGGER.warn("SNI parameter set on a non-TLS connection");
152+
}
153+
};
154+
return SocketConfigurators.defaultConfigurator().andThen(socketConfigurator);
155+
}
156+
}
157+
158+
static SslEngineConfigurator sslEngineConfigurator(CommandLineProxy cmd) {
159+
List<SNIServerName> serverNames = sniServerNames(strArg(cmd, "sni", null));
160+
if (serverNames.isEmpty()) {
161+
return SslEngineConfigurators.DEFAULT;
162+
} else {
163+
SslEngineConfigurator sslEngineConfigurator =
164+
sslEngine -> {
165+
SSLParameters sslParameters =
166+
sslEngine.getSSLParameters() == null
167+
? new SSLParameters()
168+
: sslEngine.getSSLParameters();
169+
sslParameters.setServerNames(serverNames);
170+
sslEngine.setSSLParameters(sslParameters);
171+
};
172+
return SslEngineConfigurators.defaultConfigurator().andThen(sslEngineConfigurator);
173+
}
174+
}
175+
176+
static String strArg(CommandLineProxy cmd, String opt, String def) {
177+
return cmd.getOptionValue(opt, def);
178+
}
102179

180+
static String strArg(CommandLineProxy cmd, char opt, String def) {
181+
return cmd.getOptionValue(opt, def);
182+
}
103183
}

src/test/java/com/rabbitmq/perf/CliTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static CommandLineProxy cmd(String commandLine) throws ParseException {
4646
@CsvSource({"-d testId, testId", "--id testId, testId", "'', default-test-id"})
4747
public void strArg(String commandLine, String expectedArgumentValue) throws ParseException {
4848
CommandLineProxy cmd = cmd(commandLine);
49-
String value = PerfTest.strArg(cmd, 'd', "default-test-id");
49+
String value = Utils.strArg(cmd, 'd', "default-test-id");
5050
assertEquals(expectedArgumentValue, value);
5151
}
5252

0 commit comments

Comments
 (0)