Skip to content

Commit fdda435

Browse files
author
Nick Johnson
committed
Get credentials from a CredentialsProvider, with a default
implementation that simply tracks a static username and password. Useful for reconnect scenarios where the username or password might have changed between the connect & reconnect.
1 parent 2db37db commit fdda435

File tree

6 files changed

+146
-39
lines changed

6 files changed

+146
-39
lines changed

src/main/java/com/rabbitmq/client/ConnectionFactory.java

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,40 @@
1515

1616
package com.rabbitmq.client;
1717

18-
import com.rabbitmq.client.impl.*;
18+
import static java.util.concurrent.TimeUnit.*;
19+
20+
import com.rabbitmq.client.impl.AMQConnection;
21+
import com.rabbitmq.client.impl.ConnectionParams;
22+
import com.rabbitmq.client.impl.CredentialsProvider;
23+
import com.rabbitmq.client.impl.DefaultCredentialsProvider;
24+
import com.rabbitmq.client.impl.DefaultExceptionHandler;
25+
import com.rabbitmq.client.impl.FrameHandler;
26+
import com.rabbitmq.client.impl.FrameHandlerFactory;
27+
import com.rabbitmq.client.impl.SocketFrameHandlerFactory;
1928
import com.rabbitmq.client.impl.nio.NioParams;
2029
import com.rabbitmq.client.impl.nio.SocketChannelFrameHandlerFactory;
2130
import com.rabbitmq.client.impl.recovery.AutorecoveringConnection;
22-
23-
import javax.net.SocketFactory;
24-
import javax.net.ssl.SSLContext;
25-
import javax.net.ssl.SSLSocketFactory;
26-
import javax.net.ssl.TrustManager;
2731
import java.io.IOException;
2832
import java.net.URI;
2933
import java.net.URISyntaxException;
3034
import java.net.URLDecoder;
3135
import java.security.KeyManagementException;
3236
import java.security.NoSuchAlgorithmException;
33-
import java.util.*;
34-
import java.util.concurrent.*;
35-
36-
import static java.util.concurrent.TimeUnit.*;
37+
import java.util.Arrays;
38+
import java.util.Collections;
39+
import java.util.HashMap;
40+
import java.util.List;
41+
import java.util.Map;
42+
import java.util.Properties;
43+
import java.util.concurrent.ExecutorService;
44+
import java.util.concurrent.Executors;
45+
import java.util.concurrent.ScheduledExecutorService;
46+
import java.util.concurrent.ThreadFactory;
47+
import java.util.concurrent.TimeoutException;
48+
import javax.net.SocketFactory;
49+
import javax.net.ssl.SSLContext;
50+
import javax.net.ssl.SSLSocketFactory;
51+
import javax.net.ssl.TrustManager;
3752

3853
/**
3954
* Convenience "factory" class to facilitate opening a {@link Connection} to an AMQP broker.
@@ -85,8 +100,6 @@ public class ConnectionFactory implements Cloneable {
85100

86101
private static final String FALLBACK_TLS_PROTOCOL = "TLSv1";
87102

88-
private String username = DEFAULT_USER;
89-
private String password = DEFAULT_PASS;
90103
private String virtualHost = DEFAULT_VHOST;
91104
private String host = DEFAULT_HOST;
92105
private int port = USE_DEFAULT_PORT;
@@ -107,6 +120,11 @@ public class ConnectionFactory implements Cloneable {
107120
private ScheduledExecutorService heartbeatExecutor;
108121
private SocketConfigurator socketConf = new DefaultSocketConfigurator();
109122
private ExceptionHandler exceptionHandler = new DefaultExceptionHandler();
123+
private CredentialsProvider credentialsProv = new DefaultCredentialsProvider();
124+
{
125+
credentialsProv.setUsername(DEFAULT_USER);
126+
credentialsProv.setPassword(DEFAULT_PASS);
127+
}
110128

111129
private boolean automaticRecovery = true;
112130
private boolean topologyRecovery = true;
@@ -172,33 +190,43 @@ public void setPort(int port) {
172190
* @return the AMQP user name to use when connecting to the broker
173191
*/
174192
public String getUsername() {
175-
return this.username;
193+
return credentialsProv.getUsername();
176194
}
177195

178196
/**
179197
* Set the user name.
180198
* @param username the AMQP user name to use when connecting to the broker
181199
*/
182200
public void setUsername(String username) {
183-
this.username = username;
201+
credentialsProv.setUsername(username);
184202
}
185203

186204
/**
187205
* Retrieve the password.
188206
* @return the password to use when connecting to the broker
189207
*/
190208
public String getPassword() {
191-
return this.password;
209+
return credentialsProv.getPassword();
192210
}
193211

194212
/**
195213
* Set the password.
196214
* @param password the password to use when connecting to the broker
197215
*/
198216
public void setPassword(String password) {
199-
this.password = password;
217+
credentialsProv.setPassword(password);
200218
}
201219

220+
/**
221+
* Set a custom credentials provider.
222+
* @param credentialsProvider The custom implementation of CredentialsProvider to use when connecting to the broker.
223+
* @see com.rabbitmq.client.impl.DefaultCredentialsProvider
224+
* @see com.rabbitmq.client.impl.AbstractCredentialsProvider
225+
*/
226+
public void setCredentialsProvider(CredentialsProvider credentialsProvider) {
227+
this.credentialsProv = credentialsProvider;
228+
}
229+
202230
/**
203231
* Retrieve the virtual host.
204232
* @return the virtual host to use when connecting to the broker
@@ -954,8 +982,7 @@ public Connection newConnection(ExecutorService executor, AddressResolver addres
954982
public ConnectionParams params(ExecutorService consumerWorkServiceExecutor) {
955983
ConnectionParams result = new ConnectionParams();
956984

957-
result.setUsername(username);
958-
result.setPassword(password);
985+
result.setCredentialsProvider(credentialsProv);
959986
result.setConsumerWorkServiceExecutor(consumerWorkServiceExecutor);
960987
result.setVirtualHost(virtualHost);
961988
result.setClientProperties(getClientProperties());

src/main/java/com/rabbitmq/client/impl/AMQConnection.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,7 @@ public static Map<String, Object> defaultClientProperties() {
129129
private final int requestedFrameMax;
130130
private final int handshakeTimeout;
131131
private final int shutdownTimeout;
132-
private final String username;
133-
private final String password;
132+
private final CredentialsProvider credentialsProvider;
134133
private final Collection<BlockedListener> blockedListeners = new CopyOnWriteArrayList<BlockedListener>();
135134
protected final MetricsCollector metricsCollector;
136135
private final int channelRpcTimeout;
@@ -209,8 +208,7 @@ public AMQConnection(ConnectionParams params, FrameHandler frameHandler) {
209208
public AMQConnection(ConnectionParams params, FrameHandler frameHandler, MetricsCollector metricsCollector)
210209
{
211210
checkPreconditions();
212-
this.username = params.getUsername();
213-
this.password = params.getPassword();
211+
this.credentialsProvider = params.getCredentialsProvider();
214212
this._frameHandler = frameHandler;
215213
this._virtualHost = params.getVirtualHost();
216214
this._exceptionHandler = params.getExceptionHandler();
@@ -323,8 +321,10 @@ public void start()
323321
"server offered [" + connStart.getMechanisms() + "]");
324322
}
325323

324+
String username = credentialsProvider.getUsername();
325+
String password = credentialsProvider.getPassword();
326326
LongString challenge = null;
327-
LongString response = sm.handleChallenge(null, this.username, this.password);
327+
LongString response = sm.handleChallenge(null, username, password);
328328

329329
do {
330330
Method method = (challenge == null)
@@ -341,7 +341,7 @@ public void start()
341341
connTune = (AMQP.Connection.Tune) serverResponse;
342342
} else {
343343
challenge = ((AMQP.Connection.Secure) serverResponse).getChallenge();
344-
response = sm.handleChallenge(challenge, this.username, this.password);
344+
response = sm.handleChallenge(challenge, username, password);
345345
}
346346
} catch (ShutdownSignalException e) {
347347
Method shutdownMethod = e.getReason();
@@ -1021,7 +1021,7 @@ public AMQCommand transformReply(AMQCommand command) {
10211021

10221022
@Override public String toString() {
10231023
final String virtualHost = "/".equals(_virtualHost) ? _virtualHost : "/" + _virtualHost;
1024-
return "amqp://" + this.username + "@" + getHostAddress() + ":" + getPort() + virtualHost;
1024+
return "amqp://" + credentialsProvider.getUsername() + "@" + getHostAddress() + ":" + getPort() + virtualHost;
10251025
}
10261026

10271027
private String getHostAddress() {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.rabbitmq.client.impl;
2+
3+
/**
4+
* Base class for extending to implement a concrete CredentialsProvider, used
5+
* when creating connections to the broker or reconnecting during recovery.
6+
*/
7+
public abstract class AbstractCredentialsProvider implements CredentialsProvider {
8+
9+
/* (non-Javadoc)
10+
* @see com.rabbitmq.client.impl.CredentialsProvider#getUsername()
11+
*/
12+
@Override
13+
public abstract String getUsername();
14+
15+
/* (non-Javadoc)
16+
* @see com.rabbitmq.client.impl.CredentialsProvider#getPassword()
17+
*/
18+
@Override
19+
public abstract String getPassword();
20+
21+
/**
22+
* Default implementation throws UnsupportedOperationException() but can be overridden for
23+
* classes which support setting a static username.
24+
*/
25+
@Override
26+
public void setUsername(String username) {
27+
throw new UnsupportedOperationException();
28+
}
29+
30+
/**
31+
* Default implementation throws UnsupportedOperationException() but can be overridden for
32+
* classes which support setting a static password.
33+
*/
34+
@Override
35+
public void setPassword(String password) {
36+
throw new UnsupportedOperationException();
37+
}
38+
39+
}

src/main/java/com/rabbitmq/client/impl/ConnectionParams.java

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@
2626
import java.util.concurrent.ThreadFactory;
2727

2828
public class ConnectionParams {
29-
private String username;
30-
private String password;
29+
private CredentialsProvider credentialsProvider;
3130
private ExecutorService consumerWorkServiceExecutor;
3231
private ScheduledExecutorService heartbeatExecutor;
3332
private ExecutorService shutdownExecutor;
@@ -50,12 +49,8 @@ public class ConnectionParams {
5049

5150
public ConnectionParams() {}
5251

53-
public String getUsername() {
54-
return username;
55-
}
56-
57-
public String getPassword() {
58-
return password;
52+
public CredentialsProvider getCredentialsProvider() {
53+
return credentialsProvider;
5954
}
6055

6156
public ExecutorService getConsumerWorkServiceExecutor() {
@@ -130,12 +125,8 @@ public boolean channelShouldCheckRpcResponseType() {
130125
return channelShouldCheckRpcResponseType;
131126
}
132127

133-
public void setUsername(String username) {
134-
this.username = username;
135-
}
136-
137-
public void setPassword(String password) {
138-
this.password = password;
128+
public void setCredentialsProvider(CredentialsProvider credentialsProvider) {
129+
this.credentialsProvider = credentialsProvider;
139130
}
140131

141132
public void setConsumerWorkServiceExecutor(ExecutorService consumerWorkServiceExecutor) {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.rabbitmq.client.impl;
2+
3+
/**
4+
* Provider interface for establishing credentials for connecting to the broker. Especially useful
5+
* for situations where credentials might change before a recovery takes place or where it is
6+
* convenient to plug in an outside custom implementation.
7+
*/
8+
public interface CredentialsProvider {
9+
10+
String getUsername();
11+
12+
String getPassword();
13+
14+
void setUsername(String username);
15+
16+
void setPassword(String password);
17+
18+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.rabbitmq.client.impl;
2+
3+
/**
4+
* Default implementation of a CredentialsProvider which simply holds a static
5+
* username and password.
6+
*/
7+
public class DefaultCredentialsProvider extends AbstractCredentialsProvider {
8+
9+
protected String username;
10+
protected String password;
11+
12+
@Override
13+
public String getUsername() {
14+
return username;
15+
}
16+
17+
@Override
18+
public String getPassword() {
19+
return password;
20+
}
21+
22+
@Override
23+
public void setUsername(String username) {
24+
this.username = username;
25+
}
26+
27+
@Override
28+
public void setPassword(String password) {
29+
this.password = password;
30+
}
31+
32+
}

0 commit comments

Comments
 (0)