Remove Usage of RabbitMQ http-client
Replace with `WebClient`.
This commit is contained in:
committed by
Oleg Zhurakousky
parent
9039bdc5e5
commit
48c8550753
@@ -47,13 +47,22 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.rabbitmq</groupId>
|
||||
<artifactId>http-client</artifactId>
|
||||
<version>2.1.0.RELEASE</version>
|
||||
<groupId>io.projectreactor.netty</groupId>
|
||||
<artifactId>reactor-netty</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
package org.springframework.cloud.stream.binder.rabbit.admin;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
@@ -26,15 +28,15 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.rabbitmq.http.client.Client;
|
||||
import com.rabbitmq.http.client.domain.BindingInfo;
|
||||
import com.rabbitmq.http.client.domain.ExchangeInfo;
|
||||
import com.rabbitmq.http.client.domain.QueueInfo;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.cloud.stream.binder.AbstractBinder;
|
||||
import org.springframework.cloud.stream.binder.BindingCleaner;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.web.reactive.function.client.ExchangeFilterFunctions;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.util.UriUtils;
|
||||
|
||||
/**
|
||||
* Implementation of {@link org.springframework.cloud.stream.binder.BindingCleaner} for
|
||||
@@ -65,28 +67,31 @@ public class RabbitBindingCleaner implements BindingCleaner {
|
||||
String vhost, String binderPrefix, String entity, boolean isJob) {
|
||||
|
||||
try {
|
||||
Client client = new Client(adminUri, user, pw);
|
||||
return doClean(client,
|
||||
WebClient client = WebClient.builder()
|
||||
.filter(ExchangeFilterFunctions.basicAuthentication(user, pw))
|
||||
.build();
|
||||
URI uri = new URI(adminUri);
|
||||
return doClean(client, uri,
|
||||
vhost == null ? "/" : vhost,
|
||||
binderPrefix == null ? BINDER_PREFIX : binderPrefix, entity, isJob);
|
||||
}
|
||||
catch (MalformedURLException | URISyntaxException e) {
|
||||
catch (URISyntaxException e) {
|
||||
throw new RabbitAdminException("Couldn't create a Client", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, List<String>> doClean(Client client,
|
||||
String vhost, String binderPrefix, String entity, boolean isJob) {
|
||||
private Map<String, List<String>> doClean(WebClient client,
|
||||
URI uri, String vhost, String binderPrefix, String entity, boolean isJob) {
|
||||
|
||||
LinkedList<String> removedQueues = isJob ? null
|
||||
: findStreamQueues(client, vhost, binderPrefix, entity);
|
||||
List<String> removedExchanges = findExchanges(client, vhost, binderPrefix, entity);
|
||||
: findStreamQueues(client, uri, vhost, binderPrefix, entity);
|
||||
List<String> removedExchanges = findExchanges(client, uri, vhost, binderPrefix, entity);
|
||||
// Delete the queues in reverse order to enable re-running after a partial
|
||||
// success.
|
||||
// The queue search above starts with 0 and terminates on a not found.
|
||||
if (removedQueues != null) {
|
||||
removedQueues.descendingIterator().forEachRemaining(q -> {
|
||||
client.deleteQueue(vhost, q);
|
||||
deleteQueue(client, uri, vhost, q);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("deleted queue: " + q);
|
||||
}
|
||||
@@ -98,7 +103,7 @@ public class RabbitBindingCleaner implements BindingCleaner {
|
||||
}
|
||||
// Fanout exchanges for taps
|
||||
removedExchanges.forEach(exchange -> {
|
||||
client.deleteExchange(vhost, exchange);
|
||||
deleteExchange(client, uri, vhost, exchange);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("deleted exchange: " + exchange);
|
||||
}
|
||||
@@ -109,15 +114,48 @@ public class RabbitBindingCleaner implements BindingCleaner {
|
||||
return results;
|
||||
}
|
||||
|
||||
private LinkedList<String> findStreamQueues(Client client, String vhost, String binderPrefix, String stream) {
|
||||
private void deleteQueue(WebClient client, URI uri, String vhost, String q) {
|
||||
URI deleteURI = uri
|
||||
.resolve("/api/queues/" + UriUtils.encodePathSegment(vhost, StandardCharsets.UTF_8) + "/" + q);
|
||||
client.delete()
|
||||
.uri(deleteURI)
|
||||
.retrieve()
|
||||
.toEntity(Void.class)
|
||||
.block(Duration.ofSeconds(10));
|
||||
}
|
||||
|
||||
private void deleteExchange(WebClient client, URI uri, String vhost, String ex) {
|
||||
URI deleteURI = uri
|
||||
.resolve("/api/exchanges/" + UriUtils.encodePathSegment(vhost, StandardCharsets.UTF_8) + "/" + ex);
|
||||
client.delete()
|
||||
.uri(deleteURI)
|
||||
.retrieve()
|
||||
.toEntity(Void.class)
|
||||
.block(Duration.ofSeconds(10));
|
||||
}
|
||||
|
||||
private LinkedList<String> findStreamQueues(WebClient client, URI uri, String vhost, String binderPrefix,
|
||||
String stream) {
|
||||
|
||||
String queueNamePrefix = adjustPrefix(AbstractBinder.applyPrefix(binderPrefix, stream));
|
||||
List<QueueInfo> queues = client.getQueues(vhost);
|
||||
List<Map<String, Object>> queues = getQueues(client, uri, vhost);
|
||||
return queues.stream()
|
||||
.filter(q -> q.getName().startsWith(queueNamePrefix))
|
||||
.filter(q -> ((String) q.get("name")).startsWith(queueNamePrefix))
|
||||
.map(q -> checkNoConsumers(q))
|
||||
.collect(Collectors.toCollection(LinkedList::new));
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> getQueues(WebClient client, URI uri, String vhost) {
|
||||
URI getUri = uri
|
||||
.resolve("/api/queues/" + UriUtils.encodePathSegment(vhost, StandardCharsets.UTF_8) + "/");
|
||||
return client.get()
|
||||
.uri(getUri)
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<List<Map<String, Object>>>() {
|
||||
})
|
||||
.block(Duration.ofSeconds(10));
|
||||
}
|
||||
|
||||
private String adjustPrefix(String prefix) {
|
||||
if (prefix.endsWith("*")) {
|
||||
return prefix.substring(0, prefix.length() - 1);
|
||||
@@ -127,41 +165,80 @@ public class RabbitBindingCleaner implements BindingCleaner {
|
||||
}
|
||||
}
|
||||
|
||||
private String checkNoConsumers(QueueInfo queue) {
|
||||
if (queue.getConsumerCount() != 0) {
|
||||
throw new RabbitAdminException("Queue " + queue.getName() + " is in use");
|
||||
private String checkNoConsumers(Map<String, Object> queue) {
|
||||
if ((Integer) queue.get("consumers") != 0) {
|
||||
throw new RabbitAdminException("Queue " + queue.get("name") + " is in use");
|
||||
}
|
||||
return queue.getName();
|
||||
return (String) queue.get("name");
|
||||
}
|
||||
|
||||
private List<String> findExchanges(Client client, String vhost, String binderPrefix, String entity) {
|
||||
List<ExchangeInfo> exchanges = client.getExchanges(vhost);
|
||||
private List<String> findExchanges(WebClient client, URI uri, String vhost, String binderPrefix, String entity) {
|
||||
List<Map<String, Object>> exchanges = getExchanges(client, uri, vhost);
|
||||
String exchangeNamePrefix = adjustPrefix(AbstractBinder.applyPrefix(binderPrefix, entity));
|
||||
List<String> exchangesToRemove = exchanges.stream()
|
||||
.filter(e -> e.getName().startsWith(exchangeNamePrefix))
|
||||
.filter(e -> ((String) e.get("name")).startsWith(exchangeNamePrefix))
|
||||
.map(e -> {
|
||||
System.out.println(e.getName());
|
||||
List<BindingInfo> bindingsBySource = client.getBindingsBySource(vhost, e.getName());
|
||||
return Collections.singletonMap(e.getName(), bindingsBySource);
|
||||
List<Map<String, Object>> bindingsBySource =
|
||||
getBindingsBySource(client, uri, vhost, (String) e.get("name"));
|
||||
return Collections.singletonMap((String) e.get("name"), bindingsBySource);
|
||||
})
|
||||
.map(bindingsMap -> hasNoForeignBindings(bindingsMap, exchangeNamePrefix))
|
||||
.collect(Collectors.toList());
|
||||
exchangesToRemove.stream()
|
||||
.map(exchange -> client.getExchangeBindingsByDestination(vhost, exchange))
|
||||
.map(exchange -> getExchangeBindingsByDestination(client, uri, vhost, exchange))
|
||||
.forEach(bindings -> {
|
||||
if (bindings.size() > 0) {
|
||||
throw new RabbitAdminException("Cannot delete exchange "
|
||||
+ bindings.get(0).getDestination() + "; it is a destination: " + bindings);
|
||||
+ bindings.get(0).get("destination") + "; it is a destination: " + bindings);
|
||||
}
|
||||
});
|
||||
return exchangesToRemove;
|
||||
}
|
||||
|
||||
private String hasNoForeignBindings(Map<String, List<BindingInfo>> bindings, String exchangeNamePrefix) {
|
||||
Entry<String, List<BindingInfo>> next = bindings.entrySet().iterator().next();
|
||||
for (BindingInfo binding : next.getValue()) {
|
||||
if (!"queue".equals(binding.getDestinationType())
|
||||
|| !binding.getDestination().startsWith(exchangeNamePrefix)) {
|
||||
private List<Map<String, Object>> getExchangeBindingsByDestination(WebClient client, URI uri, String vhost,
|
||||
String name) {
|
||||
|
||||
String exchange = "".equals(name) ? "amq.default" : name;
|
||||
URI getUri = uri
|
||||
.resolve("/api/exchanges/" + UriUtils.encodePathSegment(vhost, StandardCharsets.UTF_8) + "/"
|
||||
+ UriUtils.encodePathSegment(exchange, StandardCharsets.UTF_8) + "/bindings/destination");
|
||||
return client.get()
|
||||
.uri(getUri)
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<List<Map<String, Object>>>() {
|
||||
})
|
||||
.block(Duration.ofSeconds(10));
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> getBindingsBySource(WebClient client, URI uri, String vhost, String name) {
|
||||
String exchange = "".equals(name) ? "amq.default" : name;
|
||||
URI getUri = uri
|
||||
.resolve("/api/exchanges/" + UriUtils.encodePathSegment(vhost, StandardCharsets.UTF_8) + "/"
|
||||
+ UriUtils.encodePathSegment(exchange, StandardCharsets.UTF_8) + "/bindings/source");
|
||||
return client.get()
|
||||
.uri(getUri)
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<List<Map<String, Object>>>() {
|
||||
})
|
||||
.block(Duration.ofSeconds(10));
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> getExchanges(WebClient client, URI uri, String vhost) {
|
||||
URI getUri = uri
|
||||
.resolve("/api/exchanges/" + UriUtils.encodePathSegment(vhost, StandardCharsets.UTF_8) + "/");
|
||||
return client.get()
|
||||
.uri(getUri)
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<List<Map<String, Object>>>() {
|
||||
})
|
||||
.block(Duration.ofSeconds(10));
|
||||
}
|
||||
|
||||
private String hasNoForeignBindings(Map<String, List<Map<String, Object>>> bindings, String exchangeNamePrefix) {
|
||||
Entry<String, List<Map<String, Object>>> next = bindings.entrySet().iterator().next();
|
||||
for (Map<String, Object> binding : next.getValue()) {
|
||||
if (!"queue".equals(binding.get("destination_type"))
|
||||
|| !((String) binding.get("destination")).startsWith(exchangeNamePrefix)) {
|
||||
throw new RabbitAdminException("Cannot delete exchange "
|
||||
+ next.getKey() + "; it has bindings: " + bindings);
|
||||
}
|
||||
|
||||
@@ -16,16 +16,16 @@
|
||||
|
||||
package org.springframework.cloud.stream.binder.rabbit;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.rabbitmq.client.Channel;
|
||||
import com.rabbitmq.client.DefaultConsumer;
|
||||
import com.rabbitmq.http.client.Client;
|
||||
import com.rabbitmq.http.client.domain.QueueInfo;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.testcontainers.containers.RabbitMQContainer;
|
||||
@@ -42,6 +42,10 @@ import org.springframework.cloud.stream.binder.AbstractBinder;
|
||||
import org.springframework.cloud.stream.binder.rabbit.admin.RabbitAdminException;
|
||||
import org.springframework.cloud.stream.binder.rabbit.admin.RabbitBindingCleaner;
|
||||
import org.springframework.cloud.stream.binder.test.junit.rabbit.RabbitTestSupport;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.web.reactive.function.client.ExchangeFilterFunctions;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.util.UriUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
@@ -57,18 +61,18 @@ public class RabbitBinderCleanerTests {
|
||||
|
||||
private static final String BINDER_PREFIX = "binder.";
|
||||
|
||||
private static final Client client;
|
||||
private static final WebClient client;
|
||||
|
||||
static {
|
||||
try {
|
||||
client = new Client(RABBITMQ.getHttpUrl() + "/api", "guest", "guest");
|
||||
}
|
||||
catch (MalformedURLException | URISyntaxException e) {
|
||||
throw new RabbitAdminException("Couldn't create a Client", e);
|
||||
}
|
||||
client = WebClient.builder()
|
||||
.filter(ExchangeFilterFunctions
|
||||
.basicAuthentication(RABBITMQ.getAdminUsername(), RABBITMQ.getAdminPassword()))
|
||||
.build();
|
||||
}
|
||||
|
||||
@RegisterExtension
|
||||
private RabbitTestSupport rabbitTestSupport = new RabbitTestSupport(true, RABBITMQ.getAmqpPort(), RABBITMQ.getHttpPort());
|
||||
private final RabbitTestSupport rabbitTestSupport = new RabbitTestSupport(true, RABBITMQ.getAmqpPort(),
|
||||
RABBITMQ.getHttpPort());
|
||||
|
||||
@Test
|
||||
public void testCleanStream() {
|
||||
@@ -121,7 +125,7 @@ public class RabbitBinderCleanerTests {
|
||||
String consumerTag = channel.basicConsume(queueName,
|
||||
new DefaultConsumer(channel));
|
||||
try {
|
||||
waitForConsumerStateNot(queueName, 0);
|
||||
waitForConsumerState(queueName, 1);
|
||||
doClean(cleaner, stream1, false);
|
||||
fail("Expected exception");
|
||||
}
|
||||
@@ -130,7 +134,7 @@ public class RabbitBinderCleanerTests {
|
||||
.hasMessageContaining("Queue " + queueName + " is in use");
|
||||
}
|
||||
channel.basicCancel(consumerTag);
|
||||
waitForConsumerStateNot(queueName, 1);
|
||||
waitForConsumerState(queueName, 0);
|
||||
try {
|
||||
doClean(cleaner, stream1, false);
|
||||
fail("Expected exception");
|
||||
@@ -142,18 +146,27 @@ public class RabbitBinderCleanerTests {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void waitForConsumerStateNot(String queueName, long state) throws InterruptedException {
|
||||
private void waitForConsumerState(String queueName, long state)
|
||||
throws InterruptedException, URISyntaxException {
|
||||
|
||||
int n = 0;
|
||||
QueueInfo queue = client.getQueue("/", queueName);
|
||||
while (n++ < 100 && (queue == null || queue.getConsumerCount() == state)) {
|
||||
Map<String, Object> queue = getQueue("/", queueName);
|
||||
while (n++ < 100 && !requiredState(state, queue)) {
|
||||
Thread.sleep(100);
|
||||
queue = client.getQueue("/", queueName);
|
||||
queue = getQueue("/", queueName);
|
||||
}
|
||||
assertThat(n).withFailMessage(
|
||||
"Consumer state remained at " + state + " after 10 seconds")
|
||||
.isLessThan(100);
|
||||
}
|
||||
|
||||
private boolean requiredState(long state, Map<String, Object> queue) {
|
||||
Object consumers = queue.get("consumers");
|
||||
return state == 0
|
||||
? consumers == null || (Integer) consumers == 0
|
||||
: consumers != null && (Integer) consumers == state;
|
||||
}
|
||||
|
||||
});
|
||||
rabbitAdmin.deleteExchange(topic1.getName()); // easier than deleting the binding
|
||||
rabbitAdmin.declareExchange(topic1);
|
||||
@@ -186,8 +199,20 @@ public class RabbitBinderCleanerTests {
|
||||
assertThat(cleanedExchanges).hasSize(6);
|
||||
}
|
||||
|
||||
protected Map<String, Object> getQueue(String string, String queueName) throws URISyntaxException {
|
||||
URI uri = new URI(RABBITMQ.getHttpUrl())
|
||||
.resolve("/api/queues/" + UriUtils.encodePathSegment("/", StandardCharsets.UTF_8) + "/" + queueName);
|
||||
return client.get()
|
||||
.uri(uri)
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {
|
||||
})
|
||||
.block(Duration.ofSeconds(10));
|
||||
}
|
||||
|
||||
private static Map<String, List<String>> doClean(RabbitBindingCleaner cleaner, String entity, boolean isJob) {
|
||||
return cleaner.clean(RABBITMQ.getHttpUrl() + "/api", "guest", "guest", "/", BINDER_PREFIX, entity, isJob);
|
||||
return cleaner.clean(RABBITMQ.getHttpUrl() + "/api", RABBITMQ.getAdminUsername(), RABBITMQ.getAdminPassword(),
|
||||
"/", BINDER_PREFIX, entity, isJob);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ package org.springframework.cloud.stream.binder.rabbit;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
@@ -39,10 +41,6 @@ import java.util.stream.Collectors;
|
||||
import java.util.zip.Deflater;
|
||||
|
||||
import com.rabbitmq.client.LongString;
|
||||
import com.rabbitmq.http.client.Client;
|
||||
import com.rabbitmq.http.client.domain.BindingInfo;
|
||||
import com.rabbitmq.http.client.domain.ExchangeInfo;
|
||||
import com.rabbitmq.http.client.domain.QueueInfo;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -137,6 +135,8 @@ import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.retry.support.RetryTemplate;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.web.reactive.function.client.ExchangeFilterFunctions;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
@@ -156,7 +156,7 @@ import static org.mockito.Mockito.when;
|
||||
public class RabbitBinderTests extends
|
||||
PartitionCapableBinderTests<RabbitTestBinder, ExtendedConsumerProperties<RabbitConsumerProperties>, ExtendedProducerProperties<RabbitProducerProperties>> {
|
||||
|
||||
private static final RabbitMQContainer RABBITMQ = RabbitTestContainer.sharedInstance();
|
||||
protected static final RabbitMQContainer RABBITMQ = RabbitTestContainer.sharedInstance();
|
||||
|
||||
private static final String CLASS_UNDER_TEST_NAME = RabbitMessageChannelBinder.class.getSimpleName();
|
||||
|
||||
@@ -164,6 +164,23 @@ public class RabbitBinderTests extends
|
||||
|
||||
private static final String BIG_EXCEPTION_MESSAGE = new String(new byte[10_000]).replaceAll("\u0000", "x");
|
||||
|
||||
private static final WebClient client;
|
||||
|
||||
private static final URI uri;
|
||||
|
||||
static {
|
||||
client = WebClient.builder()
|
||||
.filter(ExchangeFilterFunctions
|
||||
.basicAuthentication(RABBITMQ.getAdminUsername(), RABBITMQ.getAdminPassword()))
|
||||
.build();
|
||||
try {
|
||||
uri = new URI(RABBITMQ.getHttpUrl() + "/api/");
|
||||
}
|
||||
catch (URISyntaxException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@RegisterExtension
|
||||
private final RabbitTestSupport rabbitTestSupport = new RabbitTestSupport(true, RABBITMQ.getAmqpPort(), RABBITMQ.getHttpPort());
|
||||
|
||||
@@ -566,8 +583,7 @@ public class RabbitBinderTests extends
|
||||
assertThat(container.isRunning()).isTrue();
|
||||
consumerBinding.unbind();
|
||||
assertThat(container.isRunning()).isFalse();
|
||||
Client client = new Client(adminUri());
|
||||
List<?> bindings = client.getBindingsBySource("/", exchange.getName());
|
||||
List<?> bindings = getBindingsBySource("/", exchange.getName());
|
||||
assertThat(bindings.size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@@ -642,30 +658,29 @@ public class RabbitBinderTests extends
|
||||
consumerBinding.unbind();
|
||||
assertThat(container.isRunning()).isFalse();
|
||||
assertThat(container.getQueueNames()[0]).isEqualTo(group);
|
||||
Client client = new Client(adminUri());
|
||||
List<BindingInfo> bindings = client.getBindingsBySource("/", "propsUser2");
|
||||
List<Map<String, Object>> bindings = getBindingsBySource("/", "propsUser2");
|
||||
int n = 0;
|
||||
while (n++ < 100 && bindings == null || bindings.size() < 1) {
|
||||
while (n++ < 100 && bindings == null || bindings.size() < 2) {
|
||||
Thread.sleep(100);
|
||||
bindings = client.getBindingsBySource("/", "propsUser2");
|
||||
bindings = getBindingsBySource("/", "propsUser2");
|
||||
}
|
||||
assertThat(bindings.size()).isEqualTo(2);
|
||||
assertThat(bindings.get(0).getSource()).isEqualTo("propsUser2");
|
||||
assertThat(bindings.get(0).getDestination()).isEqualTo(group);
|
||||
assertThat(bindings.get(0).getRoutingKey()).isIn("foo", "bar");
|
||||
assertThat(bindings.get(1).getSource()).isEqualTo("propsUser2");
|
||||
assertThat(bindings.get(1).getDestination()).isEqualTo(group);
|
||||
assertThat(bindings.get(1).getRoutingKey()).isIn("foo", "bar");
|
||||
assertThat(bindings.get(1).getRoutingKey()).isNotEqualTo(bindings.get(0).getRoutingKey());
|
||||
assertThat(bindings.get(0).get("source")).isEqualTo("propsUser2");
|
||||
assertThat(bindings.get(0).get("destination")).isEqualTo(group);
|
||||
assertThat(bindings.get(0).get("routing_key")).isIn("foo", "bar");
|
||||
assertThat(bindings.get(1).get("source")).isEqualTo("propsUser2");
|
||||
assertThat(bindings.get(1).get("destination")).isEqualTo(group);
|
||||
assertThat(bindings.get(1).get("routing_key")).isIn("foo", "bar");
|
||||
assertThat(bindings.get(1).get("routing_key")).isNotEqualTo(bindings.get(0).get("routing_key"));
|
||||
|
||||
ExchangeInfo exchange = client.getExchange("/", "propsUser2");
|
||||
Map<String, Object> exchange = getExchange("/", "propsUser2");
|
||||
while (n++ < 100 && exchange == null) {
|
||||
Thread.sleep(100);
|
||||
exchange = client.getExchange("/", "propsUser2");
|
||||
exchange = getExchange("/", "propsUser2");
|
||||
}
|
||||
assertThat(exchange.getType()).isEqualTo("direct");
|
||||
assertThat(exchange.isDurable()).isEqualTo(true);
|
||||
assertThat(exchange.isAutoDelete()).isEqualTo(false);
|
||||
assertThat(exchange.get("type")).isEqualTo("direct");
|
||||
assertThat(exchange.get("durable")).isEqualTo(true);
|
||||
assertThat(exchange.get("auto_delete")).isEqualTo(false);
|
||||
|
||||
verifyAutoDeclareContextClear(binder);
|
||||
}
|
||||
@@ -716,57 +731,56 @@ public class RabbitBinderTests extends
|
||||
SimpleMessageListenerContainer container = TestUtils.getPropertyValue(endpoint,
|
||||
"messageListenerContainer", SimpleMessageListenerContainer.class);
|
||||
assertThat(container.isRunning()).isTrue();
|
||||
Client client = new Client(adminUri());
|
||||
List<BindingInfo> bindings = client.getBindingsBySource("/", "propsUser3");
|
||||
List<Map<String, Object>> bindings = getBindingsBySource("/", "propsUser3");
|
||||
int n = 0;
|
||||
while (n++ < 100 && bindings == null || bindings.size() < 1) {
|
||||
Thread.sleep(100);
|
||||
bindings = client.getBindingsBySource("/", "propsUser3");
|
||||
bindings = getBindingsBySource("/", "propsUser3");
|
||||
}
|
||||
assertThat(bindings.size()).isEqualTo(1);
|
||||
assertThat(bindings.get(0).getSource()).isEqualTo("propsUser3");
|
||||
assertThat(bindings.get(0).getDestination()).isEqualTo("propsUser3.infra");
|
||||
assertThat(bindings.get(0).getRoutingKey()).isEqualTo("foo");
|
||||
assertThat(bindings.get(0).get("source")).isEqualTo("propsUser3");
|
||||
assertThat(bindings.get(0).get("destination")).isEqualTo("propsUser3.infra");
|
||||
assertThat(bindings.get(0).get("routing_key")).isEqualTo("foo");
|
||||
|
||||
bindings = client.getBindingsBySource("/", "customDLX");
|
||||
bindings = getBindingsBySource("/", "customDLX");
|
||||
n = 0;
|
||||
while (n++ < 100 && bindings == null || bindings.size() < 1) {
|
||||
Thread.sleep(100);
|
||||
bindings = client.getBindingsBySource("/", "customDLX");
|
||||
bindings = getBindingsBySource("/", "customDLX");
|
||||
}
|
||||
// assertThat(bindings.size()).isEqualTo(1);
|
||||
assertThat(bindings.get(0).getSource()).isEqualTo("customDLX");
|
||||
assertThat(bindings.get(0).getDestination()).isEqualTo("customDLQ");
|
||||
assertThat(bindings.get(0).getRoutingKey()).isEqualTo("customDLRK");
|
||||
assertThat(bindings.get(0).get("source")).isEqualTo("customDLX");
|
||||
assertThat(bindings.get(0).get("destination")).isEqualTo("customDLQ");
|
||||
assertThat(bindings.get(0).get("routing_key")).isEqualTo("customDLRK");
|
||||
|
||||
ExchangeInfo exchange = client.getExchange("/", "propsUser3");
|
||||
Map<String, Object> exchange = getExchange("/", "propsUser3");
|
||||
n = 0;
|
||||
while (n++ < 100 && exchange == null) {
|
||||
Thread.sleep(100);
|
||||
exchange = client.getExchange("/", "propsUser3");
|
||||
exchange = getExchange("/", "propsUser3");
|
||||
}
|
||||
assertThat(exchange.getType()).isEqualTo("direct");
|
||||
assertThat(exchange.isDurable()).isEqualTo(false);
|
||||
assertThat(exchange.isAutoDelete()).isEqualTo(true);
|
||||
assertThat(exchange.get("type")).isEqualTo("direct");
|
||||
assertThat(exchange.get("durable")).isEqualTo(false);
|
||||
assertThat(exchange.get("auto_delete")).isEqualTo(true);
|
||||
|
||||
exchange = client.getExchange("/", "customDLX");
|
||||
exchange = getExchange("/", "customDLX");
|
||||
n = 0;
|
||||
while (n++ < 100 && exchange == null) {
|
||||
Thread.sleep(100);
|
||||
exchange = client.getExchange("/", "customDLX");
|
||||
exchange = getExchange("/", "customDLX");
|
||||
}
|
||||
assertThat(exchange.getType()).isEqualTo("topic");
|
||||
assertThat(exchange.isDurable()).isEqualTo(true);
|
||||
assertThat(exchange.isAutoDelete()).isEqualTo(false);
|
||||
assertThat(exchange.get("type")).isEqualTo("topic");
|
||||
assertThat(exchange.get("durable")).isEqualTo(true);
|
||||
assertThat(exchange.get("auto_delete")).isEqualTo(false);
|
||||
|
||||
QueueInfo queue = client.getQueue("/", "propsUser3.infra");
|
||||
Map<String, Object> queue = getQueue("/", "propsUser3.infra");
|
||||
n = 0;
|
||||
while (n++ < 100 && queue == null || queue.getConsumerCount() == 0) {
|
||||
while (n++ < 100 && queue == null || !requiredConsumerState(1, queue)) {
|
||||
Thread.sleep(100);
|
||||
queue = client.getQueue("/", "propsUser3.infra");
|
||||
queue = getQueue("/", "propsUser3.infra");
|
||||
}
|
||||
assertThat(queue).isNotNull();
|
||||
Map<String, Object> args = queue.getArguments();
|
||||
Map<String, Object> args = (Map<String, Object>) queue.get("arguments");
|
||||
assertThat(args.get("x-expires")).isEqualTo(30_000);
|
||||
assertThat(args.get("x-max-length")).isEqualTo(10_000);
|
||||
assertThat(args.get("x-max-length-bytes")).isEqualTo(100_000);
|
||||
@@ -776,17 +790,17 @@ public class RabbitBinderTests extends
|
||||
assertThat(args.get("x-dead-letter-exchange")).isEqualTo("customDLX");
|
||||
assertThat(args.get("x-dead-letter-routing-key")).isEqualTo("customDLRK");
|
||||
assertThat(args.get("x-queue-mode")).isEqualTo("lazy");
|
||||
assertThat(queue.getExclusiveConsumerTag()).isEqualTo("testConsumerTag#0");
|
||||
assertThat(queue.get("exclusive_consumer_tag")).isEqualTo("testConsumerTag#0");
|
||||
|
||||
queue = client.getQueue("/", "customDLQ");
|
||||
queue = getQueue("/", "customDLQ");
|
||||
|
||||
n = 0;
|
||||
while (n++ < 100 && queue == null) {
|
||||
Thread.sleep(100);
|
||||
queue = client.getQueue("/", "customDLQ");
|
||||
queue = getQueue("/", "customDLQ");
|
||||
}
|
||||
assertThat(queue).isNotNull();
|
||||
args = queue.getArguments();
|
||||
args = (Map<String, Object>) queue.get("arguments");
|
||||
assertThat(args.get("x-expires")).isEqualTo(60_000);
|
||||
assertThat(args.get("x-max-length")).isEqualTo(20_000);
|
||||
assertThat(args.get("x-max-length-bytes")).isEqualTo(40_000);
|
||||
@@ -804,6 +818,7 @@ public class RabbitBinderTests extends
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testConsumerPropertiesWithHeaderExchanges() throws Exception {
|
||||
RabbitTestBinder binder = getBinder();
|
||||
@@ -828,30 +843,31 @@ public class RabbitBinderTests extends
|
||||
consumerBinding.unbind();
|
||||
assertThat(container.isRunning()).isFalse();
|
||||
assertThat(container.getQueueNames()[0]).isEqualTo("propsHeader." + group);
|
||||
Client client = new Client(adminUri());
|
||||
List<BindingInfo> bindings = client.getBindingsBySource("/", "propsHeader");
|
||||
List<Map<String, Object>> bindings = getBindingsBySource("/", "propsHeader");
|
||||
int n = 0;
|
||||
while (n++ < 100 && bindings == null || bindings.size() < 1) {
|
||||
Thread.sleep(100);
|
||||
bindings = client.getBindingsBySource("/", "propsHeader");
|
||||
bindings = getBindingsBySource("/", "propsHeader");
|
||||
}
|
||||
assertThat(bindings.size()).isEqualTo(1);
|
||||
assertThat(bindings.get(0).getSource()).isEqualTo("propsHeader");
|
||||
assertThat(bindings.get(0).getDestination()).isEqualTo("propsHeader." + group);
|
||||
assertThat(bindings.get(0).getArguments()).hasEntrySatisfying("x-match", v -> assertThat(v).isEqualTo("any"));
|
||||
assertThat(bindings.get(0).getArguments()).hasEntrySatisfying("foo", v -> assertThat(v).isEqualTo("bar"));
|
||||
assertThat(bindings.get(0).get("source")).isEqualTo("propsHeader");
|
||||
assertThat(bindings.get(0).get("destination")).isEqualTo("propsHeader." + group);
|
||||
Map<String, Object> args = (Map<String, Object>) bindings.get(0).get("arguments");
|
||||
assertThat(args).hasEntrySatisfying("x-match", v -> assertThat(v).isEqualTo("any"));
|
||||
assertThat(args).hasEntrySatisfying("foo", v -> assertThat(v).isEqualTo("bar"));
|
||||
|
||||
bindings = client.getBindingsBySource("/", "propsHeader.dlx");
|
||||
bindings = getBindingsBySource("/", "propsHeader.dlx");
|
||||
n = 0;
|
||||
while (n++ < 100 && bindings == null || bindings.size() < 1) {
|
||||
Thread.sleep(100);
|
||||
bindings = client.getBindingsBySource("/", "propsHeader.dlx");
|
||||
bindings = getBindingsBySource("/", "propsHeader.dlx");
|
||||
}
|
||||
assertThat(bindings.size()).isEqualTo(1);
|
||||
assertThat(bindings.get(0).getSource()).isEqualTo("propsHeader.dlx");
|
||||
assertThat(bindings.get(0).getDestination()).isEqualTo("propsHeader." + group + ".dlq");
|
||||
assertThat(bindings.get(0).getArguments()).hasEntrySatisfying("x-match", v -> assertThat(v).isEqualTo("any"));
|
||||
assertThat(bindings.get(0).getArguments()).hasEntrySatisfying("foo", v -> assertThat(v).isEqualTo("bar"));
|
||||
assertThat(bindings.get(0).get("source")).isEqualTo("propsHeader.dlx");
|
||||
assertThat(bindings.get(0).get("destination")).isEqualTo("propsHeader." + group + ".dlq");
|
||||
args = (Map<String, Object>) bindings.get(0).get("arguments");
|
||||
assertThat(args).hasEntrySatisfying("x-match", v -> assertThat(v).isEqualTo("any"));
|
||||
assertThat(args).hasEntrySatisfying("foo", v -> assertThat(v).isEqualTo("bar"));
|
||||
|
||||
verifyAutoDeclareContextClear(binder);
|
||||
}
|
||||
@@ -1107,22 +1123,22 @@ public class RabbitBinderTests extends
|
||||
DirectChannel moduleInputChannel = createBindableChannel("input",
|
||||
bindingProperties);
|
||||
moduleInputChannel.setBeanName("dlqTestManual");
|
||||
Client client = new Client(adminUri());
|
||||
moduleInputChannel.subscribe(new MessageHandler() {
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
// Wait until the unacked state is reflected in the admin
|
||||
QueueInfo info = client.getQueue("/", TEST_PREFIX + "dlqTestManual.default");
|
||||
Map<String, Object> info = getQueue("/", TEST_PREFIX + "dlqTestManual.default");
|
||||
int n = 0;
|
||||
while (n++ < 100 && info.getMessagesUnacknowledged() < 1L) {
|
||||
while (n++ < 100 && ( info.get("messages_unacknowledged") == null
|
||||
|| ((Long) info.get("messages_unacknowledged")) < 1L)) {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
info = client.getQueue("/", TEST_PREFIX + "dlqTestManual.default");
|
||||
info = getQueue("/", TEST_PREFIX + "dlqTestManual.default");
|
||||
}
|
||||
throw new RuntimeException("foo");
|
||||
}
|
||||
@@ -1148,12 +1164,12 @@ public class RabbitBinderTests extends
|
||||
assertThat(n).isLessThan(100);
|
||||
|
||||
n = 0;
|
||||
QueueInfo info = client.getQueue("/", TEST_PREFIX + "dlqTestManual.default");
|
||||
while (n++ < 100 && info.getMessagesUnacknowledged() > 0L) {
|
||||
Map<String, Object> info = getQueue("/", TEST_PREFIX + "dlqTestManual.default");
|
||||
while (n++ < 100 && unackedMessages(info)) {
|
||||
Thread.sleep(100);
|
||||
info = client.getQueue("/", TEST_PREFIX + "dlqTestManual.default");
|
||||
info = getQueue("/", TEST_PREFIX + "dlqTestManual.default");
|
||||
}
|
||||
assertThat(info.getMessagesUnacknowledged()).isEqualTo(0L);
|
||||
assertThat(unackedMessages(info)).isFalse();
|
||||
|
||||
consumerBinding.unbind();
|
||||
|
||||
@@ -1170,6 +1186,11 @@ public class RabbitBinderTests extends
|
||||
verifyAutoDeclareContextClear(binder);
|
||||
}
|
||||
|
||||
protected boolean unackedMessages(Map<String, Object> info) {
|
||||
Object unack = info.get("messages_unacknowledged");
|
||||
return unack != null && ((Integer) unack) > 0L;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAutoBindDLQPartionedConsumerFirst(TestInfo testInfo) throws Exception {
|
||||
@@ -2600,6 +2621,25 @@ public class RabbitBinderTests extends
|
||||
assertThat(ctx.getBeansOfType(Declarable.class)).isEmpty();
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> getBindingsBySource(String vhost, String name) {
|
||||
return RestUtils.getBindingsBySource(client, uri, vhost, name);
|
||||
}
|
||||
|
||||
private Map<String, Object> getExchange(String vhost, String name) {
|
||||
return RestUtils.getExchange(client, uri, vhost, name);
|
||||
}
|
||||
|
||||
private Map<String, Object> getQueue(String vhost, String name) {
|
||||
return RestUtils.getQueue(client, uri, vhost, name);
|
||||
}
|
||||
|
||||
private boolean requiredConsumerState(long state, Map<String, Object> queue) {
|
||||
Object consumers = queue.get("consumers");
|
||||
return state == 0
|
||||
? consumers == null || (Integer) consumers == 0
|
||||
: consumers != null && (Integer) consumers == state;
|
||||
}
|
||||
|
||||
public static class TestPartitionKeyExtractorClass
|
||||
implements PartitionKeyExtractorStrategy {
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.stream.binder.rabbit;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.util.UriUtils;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @since 4.0
|
||||
*
|
||||
*/
|
||||
public final class RestUtils {
|
||||
|
||||
private RestUtils() {
|
||||
}
|
||||
|
||||
public static List<Map<String, Object>> getBindingsBySource(WebClient client, URI uri, String vhost, String name) {
|
||||
String exchange = "".equals(name) ? "amq.default" : name;
|
||||
URI getUri = uri
|
||||
.resolve("/api/exchanges/" + UriUtils.encodePathSegment(vhost, StandardCharsets.UTF_8) + "/"
|
||||
+ UriUtils.encodePathSegment(exchange, StandardCharsets.UTF_8) + "/bindings/source");
|
||||
return client.get()
|
||||
.uri(getUri)
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<List<Map<String, Object>>>() {
|
||||
})
|
||||
.block(Duration.ofSeconds(10));
|
||||
}
|
||||
|
||||
public static Map<String, Object> getExchange(WebClient client, URI uri, String vhost, String name) {
|
||||
String exchange = "".equals(name) ? "amq.default" : name;
|
||||
URI getUri = uri
|
||||
.resolve("/api/exchanges/" + UriUtils.encodePathSegment(vhost, StandardCharsets.UTF_8) + "/"
|
||||
+ UriUtils.encodePathSegment(exchange, StandardCharsets.UTF_8));
|
||||
return client.get()
|
||||
.uri(getUri)
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {
|
||||
})
|
||||
.block(Duration.ofSeconds(10));
|
||||
}
|
||||
|
||||
public static Map<String, Object> getQueue(WebClient client, URI uri, String vhost, String name) {
|
||||
URI getUri = uri
|
||||
.resolve("/api/queues/" + UriUtils.encodePathSegment(vhost, StandardCharsets.UTF_8) + "/"
|
||||
+ UriUtils.encodePathSegment(name, StandardCharsets.UTF_8));
|
||||
return client.get()
|
||||
.uri(getUri)
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {
|
||||
})
|
||||
.block(Duration.ofSeconds(10));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.cloud.stream.binder.rabbit.integration;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -24,10 +25,6 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.rabbitmq.http.client.Client;
|
||||
import com.rabbitmq.http.client.domain.BindingInfo;
|
||||
import com.rabbitmq.http.client.domain.ExchangeInfo;
|
||||
import com.rabbitmq.http.client.domain.QueueInfo;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
@@ -60,6 +57,7 @@ import org.springframework.cloud.stream.binder.ExtendedProducerProperties;
|
||||
import org.springframework.cloud.stream.binder.ExtendedPropertiesBinder;
|
||||
import org.springframework.cloud.stream.binder.rabbit.RabbitMessageChannelBinder;
|
||||
import org.springframework.cloud.stream.binder.rabbit.RabbitTestContainer;
|
||||
import org.springframework.cloud.stream.binder.rabbit.RestUtils;
|
||||
import org.springframework.cloud.stream.binder.rabbit.properties.RabbitConsumerProperties;
|
||||
import org.springframework.cloud.stream.binder.rabbit.properties.RabbitProducerProperties;
|
||||
import org.springframework.cloud.stream.binder.rabbit.properties.RabbitProducerProperties.AlternateExchange;
|
||||
@@ -80,6 +78,8 @@ import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
|
||||
import org.springframework.retry.policy.SimpleRetryPolicy;
|
||||
import org.springframework.retry.support.RetryTemplate;
|
||||
import org.springframework.web.reactive.function.client.ExchangeFilterFunctions;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
@@ -100,6 +100,23 @@ public class RabbitBinderModuleTests {
|
||||
|
||||
private static final ConnectionFactory MOCK_CONNECTION_FACTORY = mock(ConnectionFactory.class, Mockito.RETURNS_MOCKS);
|
||||
|
||||
private static final WebClient client;
|
||||
|
||||
private static final URI uri;
|
||||
|
||||
static {
|
||||
client = WebClient.builder()
|
||||
.filter(ExchangeFilterFunctions
|
||||
.basicAuthentication(RABBITMQ.getAdminUsername(), RABBITMQ.getAdminPassword()))
|
||||
.build();
|
||||
try {
|
||||
uri = new URI(RABBITMQ.getHttpUrl() + "/api/");
|
||||
}
|
||||
catch (URISyntaxException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@RegisterExtension
|
||||
private final RabbitTestSupport rabbitTestSupport = new RabbitTestSupport(true, RABBITMQ.getAmqpPort(), RABBITMQ.getHttpPort());
|
||||
|
||||
@@ -169,21 +186,22 @@ public class RabbitBinderModuleTests {
|
||||
checkCustomizedArgs();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void checkCustomizedArgs() throws MalformedURLException, URISyntaxException, InterruptedException {
|
||||
Client client = new Client(String.format("http://guest:guest@localhost:%d/api", RABBITMQ.getHttpPort()));
|
||||
List<BindingInfo> bindings = client.getBindingsBySource("/", "process-in-0");
|
||||
List<Map<String, Object>> bindings = RestUtils.getBindingsBySource(client, uri, "/", "process-in-0");
|
||||
int n = 0;
|
||||
while (n++ < 100 && bindings == null || bindings.size() < 1) {
|
||||
Thread.sleep(100);
|
||||
bindings = client.getBindingsBySource("/", "process-in-0");
|
||||
bindings = RestUtils.getBindingsBySource(client, uri, "/", "process-in-0");
|
||||
}
|
||||
assertThat(bindings).isNotNull();
|
||||
assertThat(bindings.get(0).getArguments()).contains(entry("added.by", "customizer"));
|
||||
ExchangeInfo exchange = client.getExchange("/", "process-in-0");
|
||||
assertThat(exchange.getArguments()).contains(entry("added.by", "customizer"));
|
||||
QueueInfo queue = client.getQueue("/", bindings.get(0).getDestination());
|
||||
assertThat(queue.getArguments()).contains(entry("added.by", "customizer"));
|
||||
assertThat(queue.getArguments()).contains(entry("x-single-active-consumer", Boolean.TRUE));
|
||||
assertThat((Map<String, Object>) bindings.get(0).get("arguments")).contains(entry("added.by", "customizer"));
|
||||
Map<String, Object> exchange = RestUtils.getExchange(client, uri, "/", "process-in-0");
|
||||
assertThat((Map<String, Object>) exchange.get("arguments")).contains(entry("added.by", "customizer"));
|
||||
Map<String, Object> queue = RestUtils.getQueue(client, uri, "/", (String) bindings.get(0).get("destination"));
|
||||
Map<String, Object> args = (Map<String, Object>) queue.get("arguments");
|
||||
assertThat(args).contains(entry("added.by", "customizer"));
|
||||
assertThat(args).contains(entry("x-single-active-consumer", Boolean.TRUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user