From 0fedb24c6f39e5f4a4c1f4a648b19f6352f26703 Mon Sep 17 00:00:00 2001 From: Mark Pollack Date: Tue, 29 Oct 2019 16:14:16 -0400 Subject: [PATCH 1/2] Support amqps:// URIs in spring.rabbitmq.addresses See gh-18808 Co-Authored-By: Bryan Kelly --- .../autoconfigure/amqp/RabbitProperties.java | 17 ++++++++++++++++- .../amqp/RabbitPropertiesTests.java | 7 +++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java index 437323e04a3..d4cdb912f1a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java @@ -937,6 +937,10 @@ public class RabbitProperties { private static final int DEFAULT_PORT = 5672; + private static final String PREFIX_AMQP_SECURE = "amqps://"; + + private static final int DEFAULT_PORT_SECURE = 5671; + private String host; private int port; @@ -947,6 +951,8 @@ public class RabbitProperties { private String virtualHost; + private boolean isSecureConnection; + private Address(String input) { input = input.trim(); input = trimPrefix(input); @@ -956,6 +962,10 @@ public class RabbitProperties { } private String trimPrefix(String input) { + if (input.startsWith(PREFIX_AMQP_SECURE)) { + this.isSecureConnection = true; + return input.substring(PREFIX_AMQP_SECURE.length()); + } if (input.startsWith(PREFIX_AMQP)) { input = input.substring(PREFIX_AMQP.length()); } @@ -992,7 +1002,12 @@ public class RabbitProperties { int portIndex = input.indexOf(':'); if (portIndex == -1) { this.host = input; - this.port = DEFAULT_PORT; + if (this.isSecureConnection) { + this.port = DEFAULT_PORT_SECURE; + } + else { + this.port = DEFAULT_PORT; + } } else { this.host = input.substring(0, portIndex); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitPropertiesTests.java index e791dc94877..5670aeb8e95 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitPropertiesTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitPropertiesTests.java @@ -70,6 +70,13 @@ public class RabbitPropertiesTests { assertThat(this.properties.getPort()).isEqualTo(1234); } + @Test + void usingSecuredConnections() { + this.properties.setAddresses("amqps://root:password@otherhost,amqps://root:password2@otherhost2"); + assertThat(this.properties.determinePort()).isEqualTo(5671); + assertThat(this.properties.determineAddresses()).isEqualTo("otherhost:5671,otherhost2:5671"); + } + @Test public void determinePortReturnsPortOfFirstAddress() { this.properties.setAddresses("rabbit1.example.com:1234,rabbit2.example.com:2345"); From 4d1373c94d757ac89307fafac828bf9b40845df9 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 1 Nov 2019 08:50:26 +0200 Subject: [PATCH 2/2] Polish "Support amqps:// URIs in spring.rabbitmq.addresses" See gh-18808 --- .../amqp/RabbitAutoConfiguration.java | 2 +- .../autoconfigure/amqp/RabbitProperties.java | 28 +++++++++----- .../amqp/RabbitPropertiesTests.java | 37 +++++++++++++++---- .../main/asciidoc/spring-boot-features.adoc | 7 ++++ 4 files changed, 57 insertions(+), 17 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration.java index b91883fb299..993554ee2c1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration.java @@ -125,7 +125,7 @@ public class RabbitAutoConfiguration { map.from(properties::getRequestedHeartbeat).whenNonNull().asInt(Duration::getSeconds) .to(factory::setRequestedHeartbeat); RabbitProperties.Ssl ssl = properties.getSsl(); - if (ssl.isEnabled()) { + if (ssl.determineEnabled()) { factory.setUseSSL(true); map.from(ssl::getAlgorithm).whenNonNull().to(factory::setSslAlgorithm); map.from(ssl::getKeyStoreType).to(factory::setKeyStoreType); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java index d4cdb912f1a..349311597e2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java @@ -310,7 +310,7 @@ public class RabbitProperties { return this.template; } - public static class Ssl { + public class Ssl { /** * Whether to enable SSL support. @@ -366,6 +366,21 @@ public class RabbitProperties { return this.enabled; } + /** + * Returns whether SSL is enabled from the first address, or the configured ssl + * enabled flag if no addresses have been set. + * @return whether ssl is enabled + * @see #setAddresses(String) + * @see #isEnabled() + */ + public boolean determineEnabled() { + if (CollectionUtils.isEmpty(RabbitProperties.this.parsedAddresses)) { + return isEnabled(); + } + Address address = RabbitProperties.this.parsedAddresses.get(0); + return address.secureConnection; + } + public void setEnabled(boolean enabled) { this.enabled = enabled; } @@ -951,7 +966,7 @@ public class RabbitProperties { private String virtualHost; - private boolean isSecureConnection; + private boolean secureConnection; private Address(String input) { input = input.trim(); @@ -963,7 +978,7 @@ public class RabbitProperties { private String trimPrefix(String input) { if (input.startsWith(PREFIX_AMQP_SECURE)) { - this.isSecureConnection = true; + this.secureConnection = true; return input.substring(PREFIX_AMQP_SECURE.length()); } if (input.startsWith(PREFIX_AMQP)) { @@ -1002,12 +1017,7 @@ public class RabbitProperties { int portIndex = input.indexOf(':'); if (portIndex == -1) { this.host = input; - if (this.isSecureConnection) { - this.port = DEFAULT_PORT_SECURE; - } - else { - this.port = DEFAULT_PORT; - } + this.port = (this.secureConnection) ? DEFAULT_PORT_SECURE : DEFAULT_PORT; } else { this.host = input.substring(0, portIndex); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitPropertiesTests.java index 5670aeb8e95..917c09847df 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitPropertiesTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitPropertiesTests.java @@ -70,13 +70,6 @@ public class RabbitPropertiesTests { assertThat(this.properties.getPort()).isEqualTo(1234); } - @Test - void usingSecuredConnections() { - this.properties.setAddresses("amqps://root:password@otherhost,amqps://root:password2@otherhost2"); - assertThat(this.properties.determinePort()).isEqualTo(5671); - assertThat(this.properties.determineAddresses()).isEqualTo("otherhost:5671,otherhost2:5671"); - } - @Test public void determinePortReturnsPortOfFirstAddress() { this.properties.setAddresses("rabbit1.example.com:1234,rabbit2.example.com:2345"); @@ -96,6 +89,18 @@ public class RabbitPropertiesTests { assertThat(this.properties.determinePort()).isEqualTo(5672); } + @Test + public void determinePortUsingAmqpReturnsPortOfFirstAddress() { + this.properties.setAddresses("amqp://root:password@otherhost,amqps://root:password2@otherhost2"); + assertThat(this.properties.determinePort()).isEqualTo(5672); + } + + @Test + public void determinePortUsingAmqpsReturnsPortOfFirstAddress() { + this.properties.setAddresses("amqps://root:password@otherhost,amqp://root:password2@otherhost2"); + assertThat(this.properties.determinePort()).isEqualTo(5671); + } + @Test public void virtualHostDefaultsToNull() { assertThat(this.properties.getVirtualHost()).isNull(); @@ -229,6 +234,24 @@ public class RabbitPropertiesTests { assertThat(this.properties.determineAddresses()).isEqualTo("rabbit.example.com:1234"); } + @Test + public void determineSslUsingAmqpsReturnsStateOfFirstAddress() { + this.properties.setAddresses("amqps://root:password@otherhost,amqp://root:password2@otherhost2"); + assertThat(this.properties.getSsl().determineEnabled()).isTrue(); + } + + @Test + public void determineSslUsingAmqpReturnsStateOfFirstAddress() { + this.properties.setAddresses("amqp://root:password@otherhost,amqps://root:password2@otherhost2"); + assertThat(this.properties.getSsl().determineEnabled()).isFalse(); + } + + @Test + public void determineSslReturnFlagPropertyWhenNoAddresses() { + this.properties.getSsl().setEnabled(true); + assertThat(this.properties.getSsl().determineEnabled()).isTrue(); + } + @Test public void simpleContainerUseConsistentDefaultValues() { SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index e89beb2065b..8dbb63d29d9 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -4762,6 +4762,13 @@ For example, you might declare the following section in `application.properties` spring.rabbitmq.password=secret ---- +Alternatively, you could configure the same connection using the `addresses` attributes: + +[source,properties,indent=0] +---- + spring.rabbitmq.addresses=amqp://admin:secret@localhost +---- + If a `ConnectionNameStrategy` bean exists in the context, it will be automatically used to name connections created by the auto-configured `ConnectionFactory`. See {spring-boot-autoconfigure-module-code}/amqp/RabbitProperties.java[`RabbitProperties`] for more of the supported options.