Skip to content

Commit a58daaf

Browse files
author
Jerry Kuch
committed
Fix bug 23105: Modify Java client by adding new exceptions
ProtocolVersionMismatchException and PossibleAuthenticationFailureException analogous to those that the .NET client grew in the fix for bug 21238.
1 parent 4d453d9 commit a58daaf

File tree

5 files changed

+103
-25
lines changed

5 files changed

+103
-25
lines changed

src/com/rabbitmq/client/ConnectionFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ public Connection newConnection(Address[] addrs)
375375
try {
376376
FrameHandler frameHandler = createFrameHandler(addr);
377377
AMQConnection conn = new AMQConnection(this,
378-
frameHandler);
378+
frameHandler);
379379
conn.start();
380380
return conn;
381381
} catch (IOException e) {
@@ -403,7 +403,7 @@ public Connection newConnection() throws IOException {
403403

404404
@Override public ConnectionFactory clone(){
405405
try {
406-
return (ConnectionFactory)super.clone();
406+
return (ConnectionFactory)super.clone();
407407
} catch (CloneNotSupportedException e) {
408408
throw new Error(e);
409409
}

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

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,17 @@
3737
import java.util.Map;
3838
import java.util.HashMap;
3939
import java.util.concurrent.TimeoutException;
40-
import java.util.concurrent.ScheduledExecutorService;
41-
import java.util.concurrent.Executors;
42-
import java.util.concurrent.TimeUnit;
4340

4441
import com.rabbitmq.client.AMQP;
45-
import com.rabbitmq.client.Address;
4642
import com.rabbitmq.client.AlreadyClosedException;
4743
import com.rabbitmq.client.Channel;
4844
import com.rabbitmq.client.Command;
4945
import com.rabbitmq.client.Connection;
5046
import com.rabbitmq.client.ConnectionFactory;
5147
import com.rabbitmq.client.MissedHeartbeatException;
5248
import com.rabbitmq.client.ShutdownSignalException;
49+
import com.rabbitmq.client.impl.exceptions.PossibleAuthenticationFailureException;
50+
import com.rabbitmq.client.impl.exceptions.ProtocolVersionMismatchException;
5351
import com.rabbitmq.utility.BlockingCell;
5452
import com.rabbitmq.utility.Utility;
5553

@@ -228,7 +226,10 @@ public AMQConnection(ConnectionFactory factory,
228226
* Connection.Start/.StartOk, Connection.Tune/.TuneOk, and then
229227
* calls Connection.Open and waits for the OpenOk. Sets heartbeat
230228
* and frame max values after tuning has taken place.
231-
* @throws java.io.IOException if an error is encountered
229+
* @throws java.io.IOException if an error is encountered; IOException
230+
* subtypes ProtocolVersionMismatchException and
231+
* PossibleAuthenticationFailureException will be thrown in the
232+
* corresponding circumstances.
232233
*/
233234
public void start()
234235
throws IOException
@@ -259,40 +260,39 @@ public void start()
259260
(AMQP.Connection.Start) connStartBlocker.getReply().getMethod();
260261

261262
_serverProperties = connStart.getServerProperties();
262-
263+
263264
Version serverVersion =
264265
new Version(connStart.getVersionMajor(),
265266
connStart.getVersionMinor());
266-
267+
267268
if (!Version.checkVersion(clientVersion, serverVersion)) {
268269
_frameHandler.close(); //this will cause mainLoop to terminate
269-
//TODO: throw a more specific exception
270-
throw new IOException("protocol version mismatch: expected " +
271-
clientVersion + ", got " + serverVersion);
270+
throw new ProtocolVersionMismatchException(clientVersion,
271+
serverVersion);
272272
}
273273
} catch (ShutdownSignalException sse) {
274274
throw AMQChannel.wrap(sse);
275275
}
276-
276+
277277
LongString saslResponse = LongStringHelper.asLongString("\0" + _username +
278278
"\0" + _password);
279279
AMQImpl.Connection.StartOk startOk =
280280
new AMQImpl.Connection.StartOk(_clientProperties, "PLAIN",
281281
saslResponse, "en_US");
282-
282+
283283
AMQP.Connection.Tune connTune = null;
284284

285285
try {
286286
connTune = (AMQP.Connection.Tune) _channel0.rpc(startOk).getMethod();
287287
} catch (ShutdownSignalException e) {
288-
throw AMQChannel.wrap(e, "Possibly caused by authentication failure");
288+
throw new PossibleAuthenticationFailureException(e);
289289
}
290290

291291
int channelMax =
292292
negotiatedMaxValue(_factory.getRequestedChannelMax(),
293293
connTune.getChannelMax());
294294
_channelManager = new ChannelManager(channelMax);
295-
295+
296296
int frameMax =
297297
negotiatedMaxValue(_factory.getRequestedFrameMax(),
298298
connTune.getFrameMax());
@@ -302,7 +302,7 @@ public void start()
302302
negotiatedMaxValue(_factory.getRequestedHeartbeat(),
303303
connTune.getHeartbeat());
304304
setHeartbeat(heartbeat);
305-
305+
306306
_channel0.transmit(new AMQImpl.Connection.TuneOk(channelMax,
307307
frameMax,
308308
heartbeat));
@@ -519,7 +519,7 @@ public boolean processControlCommand(Command c)
519519
return false;
520520
} else {
521521
// Quiescing.
522-
if (method instanceof AMQP.Connection.CloseOk) {
522+
if (method instanceof AMQP.Connection.CloseOk) {
523523
// It's our final "RPC". Time to shut down.
524524
_running = false;
525525
// If Close was sent from within the MainLoop we
@@ -548,14 +548,14 @@ public void handleConnectionClose(Command closeCommand) {
548548
getHost() + ":" + getPort());
549549
scw.start();
550550
}
551-
551+
552552
private class SocketCloseWait extends Thread {
553553
private ShutdownSignalException cause;
554-
554+
555555
public SocketCloseWait(ShutdownSignalException sse) {
556556
cause = sse;
557557
}
558-
558+
559559
@Override public void run() {
560560
try {
561561
_appContinuation.uninterruptibleGet(CONNECTION_CLOSING_TIMEOUT);
@@ -574,7 +574,7 @@ public SocketCloseWait(ShutdownSignalException sse) {
574574
* Protected API - causes all attached channels to terminate with
575575
* a ShutdownSignal built from the argument, and stops this
576576
* connection from accepting further work from the application.
577-
*
577+
*
578578
* @return a shutdown signal built using the given arguments
579579
*/
580580
public ShutdownSignalException shutdown(Object reason,
@@ -656,7 +656,7 @@ public void abort(int closeCode, String closeMessage, int timeout)
656656
}
657657
}
658658

659-
/**
659+
/**
660660
* Protected API - Delegates to {@link
661661
* #close(int,String,boolean,Throwable,int,boolean) the
662662
* six-argument close method}, passing 0 for the timeout, and
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.rabbitmq.client.impl.exceptions;
2+
3+
import java.io.IOException;
4+
5+
/**
6+
* Thrown when the likely cause is an authentication failure.
7+
*/
8+
public class PossibleAuthenticationFailureException extends IOException
9+
{
10+
public PossibleAuthenticationFailureException(Throwable cause)
11+
{
12+
super("Possibly caused by authentication failure",
13+
cause);
14+
}
15+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.rabbitmq.client.impl.exceptions;
2+
3+
import com.rabbitmq.client.impl.Version;
4+
5+
import java.io.IOException;
6+
import java.net.ProtocolException;
7+
8+
/**
9+
* Thrown to indicate that the peer does not support the wire protocol version
10+
* we requested immediately after opening the TCP socket.
11+
*/
12+
public class ProtocolVersionMismatchException extends ProtocolException
13+
{
14+
private Version clientVersion;
15+
private Version serverVersion;
16+
17+
public ProtocolVersionMismatchException(Version clientVersion,
18+
Version serverVersion) {
19+
super("Protocol version mismatch: expected "
20+
+ clientVersion + ", got " + serverVersion);
21+
22+
this.clientVersion = clientVersion;
23+
this.serverVersion = serverVersion;
24+
}
25+
26+
/** The client's AMQP specification version. */
27+
public Version getClientVersion()
28+
{
29+
return clientVersion;
30+
}
31+
32+
/** The peer's AMQP specification version. */
33+
public Version getServerVersion()
34+
{
35+
return serverVersion;
36+
}
37+
38+
/** The client's AMQP specification major version. */
39+
public int getClientMajor()
40+
{
41+
return clientVersion.getMajor();
42+
}
43+
44+
/** The client's AMQP specification minor version. */
45+
public int getClientMinor()
46+
{
47+
return clientVersion.getMinor();
48+
}
49+
50+
/** The peer's AMQP specification major version. */
51+
public int getServerMajor()
52+
{
53+
return serverVersion.getMajor();
54+
}
55+
56+
/** The server's AMQP specification minor version. */
57+
public int getServerMinor()
58+
{
59+
return serverVersion.getMinor();
60+
}
61+
}

test/src/com/rabbitmq/client/test/server/Permissions.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
package com.rabbitmq.client.test.server;
3333

34+
import com.rabbitmq.client.impl.exceptions.PossibleAuthenticationFailureException;
3435
import com.rabbitmq.client.test.BrokerTestCase;
3536
import java.io.IOException;
3637
import java.util.Map;
@@ -41,7 +42,6 @@
4142
import com.rabbitmq.client.Command;
4243
import com.rabbitmq.client.Connection;
4344
import com.rabbitmq.client.ConnectionFactory;
44-
import com.rabbitmq.client.Method;
4545
import com.rabbitmq.client.QueueingConsumer;
4646
import com.rabbitmq.client.ShutdownSignalException;
4747
import com.rabbitmq.client.impl.AMQChannel;
@@ -148,8 +148,10 @@ public void testAuth()
148148
unAuthFactory.newConnection();
149149
fail("Exception expected if password is wrong");
150150
} catch (IOException e) {
151+
assertTrue(e instanceof PossibleAuthenticationFailureException);
151152
String msg = e.getMessage();
152-
assertTrue("Exception message should contain auth", msg.toLowerCase().contains("auth"));
153+
assertTrue("Exception message should contain 'auth'",
154+
msg.toLowerCase().contains("auth"));
153155
}
154156
}
155157

0 commit comments

Comments
 (0)