use of org.springframework.amqp.core.Base64UrlNamingStrategy in project spring-cloud-stream by spring-cloud.
the class RabbitBinderCleanerTests method testCleanStream.
@Test
public void testCleanStream() {
final RabbitBindingCleaner cleaner = new RabbitBindingCleaner();
final String stream1 = new Base64UrlNamingStrategy("foo").generateName();
String stream2 = stream1 + "-1";
String firstQueue = null;
CachingConnectionFactory connectionFactory = rabbitTestSupport.getResource();
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
for (int i = 0; i < 5; i++) {
String queue1Name = AbstractBinder.applyPrefix(BINDER_PREFIX, stream1 + ".default." + i);
String queue2Name = AbstractBinder.applyPrefix(BINDER_PREFIX, stream2 + ".default." + i);
if (firstQueue == null) {
firstQueue = queue1Name;
}
rabbitAdmin.declareQueue(new Queue(queue1Name, true, false, false));
rabbitAdmin.declareQueue(new Queue(queue2Name, true, false, false));
rabbitAdmin.declareQueue(new Queue(AbstractBinder.constructDLQName(queue1Name), true, false, false));
TopicExchange exchange = new TopicExchange(queue1Name);
rabbitAdmin.declareExchange(exchange);
rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue(queue1Name)).to(exchange).with(queue1Name));
exchange = new TopicExchange(queue2Name);
rabbitAdmin.declareExchange(exchange);
rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue(queue2Name)).to(exchange).with(queue2Name));
}
final TopicExchange topic1 = new TopicExchange(AbstractBinder.applyPrefix(BINDER_PREFIX, stream1 + ".foo.bar"));
rabbitAdmin.declareExchange(topic1);
rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue(firstQueue)).to(topic1).with("#"));
String foreignQueue = UUID.randomUUID().toString();
rabbitAdmin.declareQueue(new Queue(foreignQueue));
rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue(foreignQueue)).to(topic1).with("#"));
final TopicExchange topic2 = new TopicExchange(AbstractBinder.applyPrefix(BINDER_PREFIX, stream2 + ".foo.bar"));
rabbitAdmin.declareExchange(topic2);
rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue(firstQueue)).to(topic2).with("#"));
new RabbitTemplate(connectionFactory).execute(new ChannelCallback<Void>() {
@Override
public Void doInRabbit(Channel channel) throws Exception {
String queueName = AbstractBinder.applyPrefix(BINDER_PREFIX, stream1 + ".default." + 4);
String consumerTag = channel.basicConsume(queueName, new DefaultConsumer(channel));
try {
waitForConsumerStateNot(queueName, 0);
doClean(cleaner, stream1, false);
fail("Expected exception");
} catch (RabbitAdminException e) {
assertThat(e).hasMessageContaining("Queue " + queueName + " is in use");
}
channel.basicCancel(consumerTag);
waitForConsumerStateNot(queueName, 1);
try {
doClean(cleaner, stream1, false);
fail("Expected exception");
} catch (RabbitAdminException e) {
assertThat(e).hasMessageContaining("Cannot delete exchange ");
assertThat(e).hasMessageContaining("; it has bindings:");
}
return null;
}
private void waitForConsumerStateNot(String queueName, long state) throws InterruptedException {
int n = 0;
QueueInfo queue = client.getQueue("/", queueName);
while (n++ < 100 && (queue == null || queue.getConsumerCount() == state)) {
Thread.sleep(100);
queue = client.getQueue("/", queueName);
}
assertThat(n).withFailMessage("Consumer state remained at " + state + " after 10 seconds").isLessThan(100);
}
});
// easier than deleting the binding
rabbitAdmin.deleteExchange(topic1.getName());
rabbitAdmin.declareExchange(topic1);
rabbitAdmin.deleteQueue(foreignQueue);
connectionFactory.destroy();
Map<String, List<String>> cleanedMap = doClean(cleaner, stream1, false);
assertThat(cleanedMap).hasSize(2);
List<String> cleanedQueues = cleanedMap.get("queues");
// should *not* clean stream2
assertThat(cleanedQueues).hasSize(10);
for (int i = 0; i < 5; i++) {
assertThat(cleanedQueues.get(i * 2)).isEqualTo(BINDER_PREFIX + stream1 + ".default." + i);
assertThat(cleanedQueues.get(i * 2 + 1)).isEqualTo(BINDER_PREFIX + stream1 + ".default." + i + ".dlq");
}
List<String> cleanedExchanges = cleanedMap.get("exchanges");
assertThat(cleanedExchanges).hasSize(6);
// wild card *should* clean stream2
cleanedMap = doClean(cleaner, stream1 + "*", false);
assertThat(cleanedMap).hasSize(2);
cleanedQueues = cleanedMap.get("queues");
assertThat(cleanedQueues).hasSize(5);
for (int i = 0; i < 5; i++) {
assertThat(cleanedQueues.get(i)).isEqualTo(BINDER_PREFIX + stream2 + ".default." + i);
}
cleanedExchanges = cleanedMap.get("exchanges");
assertThat(cleanedExchanges).hasSize(6);
}
use of org.springframework.amqp.core.Base64UrlNamingStrategy in project spring-cloud-stream by spring-cloud.
the class RabbitExchangeQueueProvisioner method doProvisionConsumerDestination.
private ConsumerDestination doProvisionConsumerDestination(String name, String group, ExtendedConsumerProperties<RabbitConsumerProperties> properties) {
boolean anonymous = !StringUtils.hasText(group);
String anonymousGroup = null;
if (anonymous) {
anonymousGroup = new Base64UrlNamingStrategy(properties.getExtension().getAnonymousGroupPrefix() == null ? "" : properties.getExtension().getAnonymousGroupPrefix()).generateName();
}
String baseQueueName;
if (properties.getExtension().isQueueNameGroupOnly()) {
baseQueueName = anonymous ? anonymousGroup : group;
} else {
baseQueueName = groupedName(name, anonymous ? anonymousGroup : group);
}
if (this.logger.isInfoEnabled()) {
this.logger.info("declaring queue for inbound: " + baseQueueName + ", bound to: " + name);
}
String prefix = properties.getExtension().getPrefix();
final String exchangeName = applyPrefix(prefix, name);
Exchange exchange = buildExchange(properties.getExtension(), exchangeName);
if (properties.getExtension().isDeclareExchange()) {
declareExchange(exchangeName, anonymous ? anonymousGroup : group, exchange);
}
String queueName = applyPrefix(prefix, baseQueueName);
boolean partitioned = !anonymous && properties.isPartitioned();
boolean durable = !anonymous && properties.getExtension().isDurableSubscription();
Queue queue;
if (anonymous) {
String anonQueueName = queueName;
queue = new AnonymousQueue((org.springframework.amqp.core.NamingStrategy) () -> anonQueueName, queueArgs(queueName, properties.getExtension(), false));
} else {
if (partitioned) {
String partitionSuffix = "-" + properties.getInstanceIndex();
queueName += partitionSuffix;
}
if (durable) {
queue = new Queue(queueName, true, false, false, queueArgs(queueName, properties.getExtension(), false));
} else {
queue = new Queue(queueName, false, false, true, queueArgs(queueName, properties.getExtension(), false));
}
}
Binding binding = null;
if (properties.getExtension().isBindQueue()) {
if (properties.getExtension().getContainerType().equals(ContainerType.STREAM)) {
queue.getArguments().put("x-queue-type", "stream");
}
declareQueue(queueName, queue);
String[] routingKeys = bindingRoutingKeys(properties.getExtension());
if (ObjectUtils.isEmpty(routingKeys)) {
binding = declareConsumerBindings(name, null, properties, exchange, partitioned, queue);
} else {
for (String routingKey : routingKeys) {
binding = declareConsumerBindings(name, routingKey, properties, exchange, partitioned, queue);
}
}
}
if (durable) {
autoBindDLQ(applyPrefix(properties.getExtension().getPrefix(), baseQueueName), queueName, group, properties.getExtension());
}
return new RabbitConsumerDestination(queue.getName(), binding, anonymous ? baseQueueName : group, name);
}
Aggregations