GH-203: Support Late Binding with RabbitMQ

If the broker was down, the binding failed. Defer the queue/exchange/binding declarations
until the broker is available (already supported by `RabbitAdmin`.

Solves spring-cloud/spring-cloud-stream#203

Fix PubSub, Test

- Too many binder prefixes on pub sub queue name.
- Mismatched queue args in test case.
This commit is contained in:
Gary Russell
2015-11-18 16:15:50 -05:00
committed by Marius Bogoevici
parent 2d245c0424
commit d3c87daf64
3 changed files with 302 additions and 77 deletions

View File

@@ -16,8 +16,15 @@
package org.springframework.cloud.stream.test.junit.rabbit;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
@@ -58,4 +65,102 @@ public class RabbitTestSupport extends AbstractExternalResourceTestSupport<Cachi
resource.destroy();
}
/**
* Test class to allow testing deferred entity declarations when RabbitMQ is down.
*
*/
public static class RabbitProxy {
private final int port;
private final ExecutorService serverExec = Executors.newSingleThreadExecutor();
private final ExecutorService socketExec = Executors.newCachedThreadPool();
private volatile ServerSocket serverSocket;
public RabbitProxy() throws IOException {
ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket(0);
this.port = serverSocket.getLocalPort();
serverSocket.close();
}
public int getPort() {
return this.port;
}
public void start() throws IOException {
this.serverSocket = ServerSocketFactory.getDefault().createServerSocket(this.port);
this.serverExec.execute(new Runnable() {
@Override
public void run() {
try {
while (true) {
final Socket socket = serverSocket.accept();
socketExec.execute(new Runnable() {
@Override
public void run() {
try {
final Socket rabbitSocket = SocketFactory.getDefault().createSocket("localhost",
5672);
socketExec.execute(new Runnable() {
@Override
public void run() {
try {
InputStream is = rabbitSocket.getInputStream();
OutputStream os = socket.getOutputStream();
int c;
while ((c = is.read()) >= 0) {
os.write(c);
}
}
catch (IOException e) {
try {
socket.close();
rabbitSocket.close();
}
catch (IOException e1) {
}
}
}
});
InputStream is = socket.getInputStream();
OutputStream os = rabbitSocket.getOutputStream();
int c;
while ((c = is.read()) >= 0) {
os.write(c);
}
}
catch (IOException e) {
try {
socket.close();
}
catch (IOException e1) {
}
}
}
});
}
}
catch (IOException e) {
try {
serverSocket.close();
}
catch (IOException e1) {
}
}
}
});
}
public void stop() throws IOException {
this.serverSocket.close();
}
}
}