From 5af4e0fce762b23f3a1ac92a56e79dcf2bc1f926 Mon Sep 17 00:00:00 2001 From: Almog Tavor Date: Wed, 6 Apr 2022 22:01:18 +0300 Subject: [PATCH 01/12] Add Reactor Kafka autoconfiguration support --- .../spring-boot-autoconfigure/build.gradle | 1 + .../kafka/DefaultKafkaReceiverCustomizer.java | 36 ++ .../kafka/DefaultKafkaSenderCustomizer.java | 37 ++ .../kafka/ReactiveKafkaAutoConfiguration.java | 119 +++++++ .../kafka/ReactiveKafkaProperties.java | 333 ++++++++++++++++++ .../ReactiveKafkaAutoConfigurationTests.java | 81 +++++ 6 files changed, 607 insertions(+) create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaReceiverCustomizer.java create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaSenderCustomizer.java create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java diff --git a/spring-boot-project/spring-boot-autoconfigure/build.gradle b/spring-boot-project/spring-boot-autoconfigure/build.gradle index fc32ecfd4896..8a8a20c37aa5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-autoconfigure/build.gradle @@ -188,6 +188,7 @@ dependencies { optional("org.thymeleaf.extras:thymeleaf-extras-java8time") optional("org.thymeleaf.extras:thymeleaf-extras-springsecurity6") optional("redis.clients:jedis") + optional("io.projectreactor.kafka:reactor-kafka") testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) testImplementation(project(":spring-boot-project:spring-boot-test")) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaReceiverCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaReceiverCustomizer.java new file mode 100644 index 000000000000..38291a9348a7 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaReceiverCustomizer.java @@ -0,0 +1,36 @@ +/* + * Copyright 2012-2020 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.boot.autoconfigure.kafka; + +import reactor.kafka.receiver.internals.DefaultKafkaReceiver; + +/** + * Callback interface for customizing {@code reactor.kafka.receiver.internals.DefaultKafkaReceiver} beans. + * + * @author Almog Tavor + * @since 2.7.0 + */ +@FunctionalInterface +public interface DefaultKafkaReceiverCustomizer { + + /** + * Customize the {@link DefaultKafkaReceiver}. + * @param receiverFactory the receiver factory to customize + */ + void customize(DefaultKafkaReceiver receiverFactory); + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaSenderCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaSenderCustomizer.java new file mode 100644 index 000000000000..013cb3ad1c1b --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaSenderCustomizer.java @@ -0,0 +1,37 @@ +/* + * Copyright 2012-2020 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.boot.autoconfigure.kafka; + +import reactor.kafka.sender.internals.DefaultKafkaSender; + +/** + * Callback interface for customizing {@code reactor.kafka.sender.internals.DefaultKafkaSender} beans. + * + * @author Almog Tavor + * @since 2.7.0 + */ +@FunctionalInterface +public interface DefaultKafkaSenderCustomizer { + + /** + * Customize the {@link DefaultKafkaSender}. + * + * @param senderFactory the consumer factory to customize + */ + void customize(DefaultKafkaSender senderFactory); + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java new file mode 100644 index 000000000000..89bc2a0bad67 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java @@ -0,0 +1,119 @@ +/* + * Copyright 2012-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.boot.autoconfigure.kafka; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import reactor.kafka.receiver.KafkaReceiver; +import reactor.kafka.receiver.ReceiverOptions; +import reactor.kafka.sender.KafkaSender; +import reactor.kafka.sender.SenderOptions; + +import java.time.Duration; +import java.util.Collection; +import java.util.Map; +import java.util.Optional; +import java.util.regex.Pattern; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for the Reactive client of Apache Kafka. + * + * @author Almog Tavor + * @since 2.7.0 + */ +@AutoConfiguration +@ConditionalOnClass({KafkaReceiver.class, KafkaSender.class}) +@ConditionalOnBean(KafkaProperties.class) +@EnableConfigurationProperties(ReactiveKafkaProperties.class) +public class ReactiveKafkaAutoConfiguration { + private final KafkaProperties kafkaProperties; + private final ReactiveKafkaProperties reactiveKafkaProperties; + + public ReactiveKafkaAutoConfiguration(KafkaProperties kafkaProperties, ReactiveKafkaProperties reactiveKafkaProperties) { + this.kafkaProperties = kafkaProperties; + this.reactiveKafkaProperties = reactiveKafkaProperties; + } + + @Bean + @ConditionalOnMissingBean(ReceiverOptions.class) + public ReceiverOptions receiverOptions() { + Map properties = kafkaProperties.buildConsumerProperties(); + properties.putAll(this.reactiveKafkaProperties.buildReceiverProperties()); + ReceiverOptions receiverOptions = ReceiverOptions.create(properties); + int atmostOnceCommitAheadSize = this.reactiveKafkaProperties.getReceiver().getAtmostOnceCommitAheadSize(); + if (atmostOnceCommitAheadSize >= 0) { + receiverOptions = receiverOptions.atmostOnceCommitAheadSize(atmostOnceCommitAheadSize); + } + Optional closeTimeout = Optional.ofNullable(this.reactiveKafkaProperties.getReceiver().getCloseTimeout()); + if (closeTimeout.isPresent()) { + receiverOptions = receiverOptions.closeTimeout(closeTimeout.get()); + } + Optional pollTimeout = Optional.ofNullable(this.reactiveKafkaProperties.getReceiver().getPollTimeout()); + if (pollTimeout.isPresent()) { + receiverOptions = receiverOptions.pollTimeout(pollTimeout.get()); + } + int maxDeferredCommits = this.reactiveKafkaProperties.getReceiver().getMaxDeferredCommits(); + if (maxDeferredCommits >= 0) { + receiverOptions = receiverOptions.maxDeferredCommits(maxDeferredCommits); + } + int maxCommitAttempts = this.reactiveKafkaProperties.getReceiver().getMaxCommitAttempts(); + if (maxCommitAttempts >= 0) { + receiverOptions = receiverOptions.maxCommitAttempts(maxCommitAttempts); + } + int commitBatchSize = this.reactiveKafkaProperties.getReceiver().getCommitBatchSize(); + if (commitBatchSize >= 0) { + receiverOptions = receiverOptions.commitBatchSize(commitBatchSize); + } + Duration commitInterval = this.reactiveKafkaProperties.getReceiver().getCommitInterval(); + if (commitInterval != null) { + receiverOptions = receiverOptions.commitInterval(commitInterval.get()); + } + Collection subscribeTopics = this.reactiveKafkaProperties.getReceiver().getSubscribeTopics(); + if (subscribeTopics != null) { + receiverOptions = receiverOptions.subscription(subscribeTopics); + } else { + Optional subscribePattern = Optional.of(this.reactiveKafkaProperties.getReceiver().getSubscribePattern()); + if (subscribePattern.isPresent()) { + receiverOptions = receiverOptions.subscription(subscribePattern.get()); + } + } + return receiverOptions; + } + + @Bean + @ConditionalOnMissingBean(SenderOptions.class) + public SenderOptions senderOptions() { + Map properties = kafkaProperties.buildProducerProperties(); + properties.putAll(this.reactiveKafkaProperties.buildSenderProperties()); + SenderOptions senderOptions = SenderOptions.create(properties); + Duration closeTimeout = this.reactiveKafkaProperties.getSender().getCloseTimeout(); + if (closeTimeout != null) { + senderOptions = senderOptions.closeTimeout(closeTimeout); + } + int maxInFlight = this.reactiveKafkaProperties.getSender().getMaxInFlight(); + if (maxInFlight >= 0) { + senderOptions = senderOptions.maxInFlight(maxInFlight); + } + senderOptions = senderOptions.stopOnError(this.reactiveKafkaProperties.getSender().isStopOnError()); + return senderOptions; + } +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java new file mode 100644 index 000000000000..636adcbbf007 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java @@ -0,0 +1,333 @@ +/* + * Copyright 2012-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.boot.autoconfigure.kafka; + +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.consumer.RetriableCommitFailedException; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.util.CollectionUtils; +import reactor.kafka.receiver.KafkaReceiver; + +import java.time.Duration; +import java.util.*; +import java.util.regex.Pattern; + +/** + * Configuration properties for Project Reactor for Apache Kafka. + *

+ * Users should refer to Reactor Kafka documentation for complete descriptions of these + * properties. + * + * @author Almog Tavor + * @since 2.7.0 + */ +@ConfigurationProperties(prefix = "spring.reactor.kafka") +public class ReactiveKafkaProperties { + /** + * Additional properties, common to producers and consumers, used to configure the + * client. + */ + private final Map properties = new HashMap<>(); + + private final Receiver receiver = new Receiver(); + + private final Sender sender = new Sender(); + + public Map getProperties() { + return this.properties; + } + + public Receiver getReceiver() { + return this.receiver; + } + + public Sender getSender() { + return this.sender; + } + + + private Map buildCommonProperties() { + Map commonProperties = new HashMap<>(); + if (!CollectionUtils.isEmpty(this.properties)) { + commonProperties.putAll(this.properties); + } + return commonProperties; + } + + /** + * Create an initial map of consumer properties from the state of this instance. + *

+ * This allows you to add additional properties, if necessary, and override the + * default kafkaReceiver bean. + * + * @return the consumer properties initialized with the customizations defined on this + * instance + */ + public Map buildReceiverProperties() { + Map receiverProperties = buildCommonProperties(); + receiverProperties.putAll(this.receiver.buildProperties()); + return receiverProperties; + } + + /** + * Create an initial map of producer properties from the state of this instance. + * This allows you to add additional properties, if necessary, and override the + * default kafkaSender bean. + * + * @return the producer properties initialized with the customizations defined on this + * instance + */ + public Map buildSenderProperties() { + Map senderProperties = buildCommonProperties(); + senderProperties.putAll(this.sender.buildProperties()); + return senderProperties; + } + + + public static class Receiver { + /** + * Sets the timeout for each {@link KafkaConsumer#poll(Duration)} operation. Since + * the underlying Kafka consumer is not thread-safe, long poll intervals may delay + * commits and other operations invoked using {@link KafkaReceiver#doOnConsumer(java.util.function.Function)}. + * Very short timeouts may reduce batching and increase load on the broker. + */ + private Duration pollTimeout; + + /** + * Sets timeout for graceful shutdown of {@link KafkaConsumer}. + */ + private Duration closeTimeout; + + /** + * Sets subscription using group management to the specified collection of topics. + */ + private Collection subscribeTopics; + + /** + * Sets subscription using group management to the specified pattern. + */ + private Pattern subscribePattern; + + /** + * Configures commit interval for automatic commits. At least one commit operation is + * attempted within this interval if records are consumed and acknowledged. + */ + private Duration commitInterval; + + + /** + * Configures commit batch size for automatic commits. At least one commit operation is + * attempted when the number of acknowledged uncommitted offsets reaches this batch size. + */ + private int commitBatchSize; + + /** + * Configures commit ahead size per partition for at-most-once delivery. Before dispatching + * each record, an offset ahead by this size may be committed. The maximum number + * of records that may be lost if the application fails is commitAheadSize + 1. + */ + private int atmostOnceCommitAheadSize; + + /** + * Configures the maximum number of consecutive non-fatal {@link RetriableCommitFailedException} + * commit failures that are tolerated. For manual commits, failure in commit after the configured + * number of attempts fails the commit operation. For auto commits, the received Flux is terminated + * if the commit does not succeed after these attempts. + */ + private int maxCommitAttempts; + + /** + * Set to greater than 0 to enable out of order commit sequencing. If the number of + * deferred commits exceeds this value, the consumer is paused until the deferred + * commits are reduced. + */ + private int maxDeferredCommits; + + public Duration getPollTimeout() { + return pollTimeout; + } + + public void setPollTimeout(Duration pollTimeout) { + this.pollTimeout = pollTimeout; + } + + public Duration getCloseTimeout() { + return closeTimeout; + } + + public void setCloseTimeout(Duration closeTimeout) { + this.closeTimeout = closeTimeout; + } + + public Collection getSubscribeTopics() { + return subscribeTopics; + } + + public void setSubscribeTopics(Collection subscribeTopics) { + this.subscribeTopics = subscribeTopics; + } + + public Pattern getSubscribePattern() { + return subscribePattern; + } + + public void setSubscribePattern(Pattern subscribePattern) { + this.subscribePattern = subscribePattern; + } + + public Duration getCommitInterval() { + return commitInterval; + } + + public void setCommitInterval(Duration commitInterval) { + this.commitInterval = commitInterval; + } + + public int getCommitBatchSize() { + return commitBatchSize; + } + + public void setCommitBatchSize(int commitBatchSize) { + this.commitBatchSize = commitBatchSize; + } + + public int getAtmostOnceCommitAheadSize() { + return atmostOnceCommitAheadSize; + } + + public void setAtmostOnceCommitAheadSize(int atmostOnceCommitAheadSize) { + this.atmostOnceCommitAheadSize = atmostOnceCommitAheadSize; + } + + public int getMaxCommitAttempts() { + return maxCommitAttempts; + } + + public void setMaxCommitAttempts(int maxCommitAttempts) { + this.maxCommitAttempts = maxCommitAttempts; + } + + public int getMaxDeferredCommits() { + return maxDeferredCommits; + } + + public void setMaxDeferredCommits(int maxDeferredCommits) { + this.maxDeferredCommits = maxDeferredCommits; + } + + public Map buildProperties() { + Properties receiverProperties = new Properties(); + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + map.from(this::getPollTimeout).asInt(Duration::toMillis).to(receiverProperties.in("pollTimeout")); + map.from(this::getCloseTimeout).asInt(Duration::toMillis).to(receiverProperties.in("closeTimeout")); + map.from(this::getCommitInterval).asInt(Duration::toMillis).to(receiverProperties.in("commitInterval")); + map.from(this::getCommitBatchSize).to(receiverProperties.in("commitBatchSize")); + map.from(this::getAtmostOnceCommitAheadSize).to(receiverProperties.in("atmostOnceCommitAheadSize")); + map.from(this::getMaxCommitAttempts).to(receiverProperties.in("maxCommitAttempts")); + map.from(this::getMaxDeferredCommits).to(receiverProperties.in("maxDeferredCommits")); + map.from(this::getSubscribeTopics).to(receiverProperties.in("subscribeTopics")); + map.from(this::getSubscribePattern).to(receiverProperties.in("subscribePattern")); + return receiverProperties; + } + } + + public static class Sender { + + private final Map properties = new HashMap<>(); + + /** + * Configures the maximum number of in-flight records that are fetched + * from the outbound record publisher while acknowledgements are pending. + * This limit must be configured along with {@link ProducerConfig#BUFFER_MEMORY_CONFIG} + * to control memory usage and to avoid blocking the reactive pipeline. + */ + private int maxInFlight; + + + /** + * Configures error handling behaviour for {@link reactor.kafka.sender.KafkaSender#send(org.reactivestreams.Publisher)}. + * If set to true, send fails when an error is encountered and only records + * that are already in transit may be delivered after the first error. If set to false, + * an attempt is made to send each record to Kafka, even if one or more records cannot + * be delivered after the configured number of retries due to a non-fatal exception. + * This flag should be set along with {@link ProducerConfig#RETRIES_CONFIG} and + * {@link ProducerConfig#ACKS_CONFIG} to configure the required quality-of-service. + * By default, stopOnError is true. + */ + private boolean stopOnError; + + /** + * Configures the timeout for graceful shutdown of this sender. + */ + private Duration closeTimeout; + + public int getMaxInFlight() { + return maxInFlight; + } + + public void setMaxInFlight(int maxInFlight) { + this.maxInFlight = maxInFlight; + } + + public boolean isStopOnError() { + return stopOnError; + } + + public void setStopOnError(boolean stopOnError) { + this.stopOnError = stopOnError; + } + + public Duration getCloseTimeout() { + return closeTimeout; + } + + public void setCloseTimeout(Duration closeTimeout) { + this.closeTimeout = closeTimeout; + } + + public Map getProperties() { + return this.properties; + } + + public Map buildProperties() { + Properties senderProperties = new Properties(); + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + map.from(this::getCloseTimeout).asInt(Duration::toMillis).to(senderProperties.in("closeTimeout")); + map.from(this::isStopOnError).to(senderProperties.in("stopOnError")); + map.from(this::getMaxInFlight).to(senderProperties.in("maxInFlight")); + return senderProperties; + } + } + + @SuppressWarnings("serial") + public static class Properties extends HashMap { + + public java.util.function.Consumer in(String key) { + return (value) -> put(key, value); + } + + public Properties with(KafkaProperties.Ssl ssl, KafkaProperties.Security security, Map properties) { + putAll(ssl.buildProperties()); + putAll(security.buildProperties()); + putAll(properties); + return this; + } + + } +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java new file mode 100644 index 000000000000..9ddcde65100c --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java @@ -0,0 +1,81 @@ +/* + * Copyright 2012-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.boot.autoconfigure.kafka; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import reactor.kafka.receiver.ReceiverOptions; +import reactor.kafka.sender.SenderOptions; + +import java.util.Arrays; +import java.util.Map; +import java.util.Objects; +import java.util.regex.Pattern; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ReactiveKafkaAutoConfiguration}. + * + * @author Almog Tavor + */ +class ReactiveKafkaAutoConfigurationTests { + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(KafkaAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(ReactiveKafkaAutoConfiguration.class)); + + @Test + void receiverProperties() { + this.contextRunner.withPropertyValues( + "spring.reactor.kafka.receiver.commit-interval=2000", "spring.reactor.kafka.receiver.close-timeout=1500", + "spring.reactor.kafka.receiver.commit-batch-size=100", "spring.reactor.kafka.receiver.poll-timeout=1000", + "spring.reactor.kafka.receiver.atmost-once-commit-ahead-size=42", "spring.reactor.kafka.receiver.max-commit-attempts=3", + "spring.reactor.kafka.receiver.max-deferred-commits=5", "spring.reactor.kafka.receiver.subscribe-topics=foo,bar", + "spring.reactor.kafka.receiver.subscribe-pattern=myTopic.+") + .run((context) -> { + ReceiverOptions receiverOptions = context + .getBean(ReceiverOptions.class); + Map configs = receiverOptions.consumerProperties(); + assertThat(configs.get("commitInterval")).isEqualTo(2000); + assertThat(configs.get("closeTimeout")).isEqualTo(1500); + assertThat(configs.get("commitBatchSize")).isEqualTo(100); + assertThat(configs.get("pollTimeout")).isEqualTo(1000); + assertThat(configs.get("atmostOnceCommitAheadSize")).isEqualTo(42); + assertThat(configs.get("maxCommitAttempts")).isEqualTo(3); + assertThat(configs.get("maxDeferredCommits")).isEqualTo(5); + assertThat(configs.get("subscribeTopics")).isEqualTo(Arrays.asList("foo", "bar")); + assertThat((Pattern) configs.get("subscribePattern")) + .matches(p -> Objects.equals(Pattern.compile("myTopic.+").pattern(), p.pattern())); + }); + } + + @Test + void producerProperties() { + this.contextRunner.withPropertyValues( + "spring.reactor.kafka.sender.max-in-flight=1500", "spring.reactor.kafka.sender.stop-on-error=false", + "spring.reactor.kafka.sender.close-timeout=500") + .run((context) -> { + SenderOptions senderOptions = context + .getBean(SenderOptions.class); + Map configs = senderOptions.producerProperties(); + assertThat(configs.get("maxInFlight")).isEqualTo(1500); + assertThat((Boolean) configs.get("stopOnError")).isFalse(); + assertThat(configs.get("closeTimeout")).isEqualTo(500); + }); + } +} From 518e7c2483e64e01aa700aa06db1e643902e76ff Mon Sep 17 00:00:00 2001 From: Almog Tavor Date: Thu, 7 Apr 2022 22:40:05 +0300 Subject: [PATCH 02/12] Fix: minor syntax bug --- .../kafka/ReactiveKafkaAutoConfiguration.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java index 89bc2a0bad67..c29a2e02bf38 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java @@ -85,15 +85,15 @@ public ReceiverOptions receiverOptions() { } Duration commitInterval = this.reactiveKafkaProperties.getReceiver().getCommitInterval(); if (commitInterval != null) { - receiverOptions = receiverOptions.commitInterval(commitInterval.get()); + receiverOptions = receiverOptions.commitInterval(commitInterval); } Collection subscribeTopics = this.reactiveKafkaProperties.getReceiver().getSubscribeTopics(); if (subscribeTopics != null) { receiverOptions = receiverOptions.subscription(subscribeTopics); } else { - Optional subscribePattern = Optional.of(this.reactiveKafkaProperties.getReceiver().getSubscribePattern()); - if (subscribePattern.isPresent()) { - receiverOptions = receiverOptions.subscription(subscribePattern.get()); + Pattern subscribePattern = this.reactiveKafkaProperties.getReceiver().getSubscribePattern(); + if (subscribePattern != null) { + receiverOptions = receiverOptions.subscription(subscribePattern); } } return receiverOptions; From 091b4d57f007aa735774ee197d8d046ab979edeb Mon Sep 17 00:00:00 2001 From: Almog Tavor Date: Fri, 8 Apr 2022 12:26:22 +0300 Subject: [PATCH 03/12] Fix: formatting --- .../kafka/DefaultKafkaReceiverCustomizer.java | 13 +- .../kafka/DefaultKafkaSenderCustomizer.java | 14 +- .../kafka/ReactiveKafkaAutoConfiguration.java | 142 +++-- .../kafka/ReactiveKafkaProperties.java | 587 +++++++++--------- .../ReactiveKafkaAutoConfigurationTests.java | 83 +-- 5 files changed, 427 insertions(+), 412 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaReceiverCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaReceiverCustomizer.java index 38291a9348a7..e86785f5ea28 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaReceiverCustomizer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaReceiverCustomizer.java @@ -19,7 +19,8 @@ import reactor.kafka.receiver.internals.DefaultKafkaReceiver; /** - * Callback interface for customizing {@code reactor.kafka.receiver.internals.DefaultKafkaReceiver} beans. + * Callback interface for customizing + * {@code reactor.kafka.receiver.internals.DefaultKafkaReceiver} beans. * * @author Almog Tavor * @since 2.7.0 @@ -27,10 +28,10 @@ @FunctionalInterface public interface DefaultKafkaReceiverCustomizer { - /** - * Customize the {@link DefaultKafkaReceiver}. - * @param receiverFactory the receiver factory to customize - */ - void customize(DefaultKafkaReceiver receiverFactory); + /** + * Customize the {@link DefaultKafkaReceiver}. + * @param receiverFactory the receiver factory to customize + */ + void customize(DefaultKafkaReceiver receiverFactory); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaSenderCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaSenderCustomizer.java index 013cb3ad1c1b..02cd4eff3709 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaSenderCustomizer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/DefaultKafkaSenderCustomizer.java @@ -19,7 +19,8 @@ import reactor.kafka.sender.internals.DefaultKafkaSender; /** - * Callback interface for customizing {@code reactor.kafka.sender.internals.DefaultKafkaSender} beans. + * Callback interface for customizing + * {@code reactor.kafka.sender.internals.DefaultKafkaSender} beans. * * @author Almog Tavor * @since 2.7.0 @@ -27,11 +28,10 @@ @FunctionalInterface public interface DefaultKafkaSenderCustomizer { - /** - * Customize the {@link DefaultKafkaSender}. - * - * @param senderFactory the consumer factory to customize - */ - void customize(DefaultKafkaSender senderFactory); + /** + * Customize the {@link DefaultKafkaSender}. + * @param senderFactory the consumer factory to customize + */ + void customize(DefaultKafkaSender senderFactory); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java index c29a2e02bf38..97a554fe8b2f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java @@ -35,85 +35,93 @@ import java.util.regex.Pattern; /** - * {@link EnableAutoConfiguration Auto-configuration} for the Reactive client of Apache Kafka. + * {@link EnableAutoConfiguration Auto-configuration} for the Reactive client of Apache + * Kafka. * * @author Almog Tavor * @since 2.7.0 */ @AutoConfiguration -@ConditionalOnClass({KafkaReceiver.class, KafkaSender.class}) +@ConditionalOnClass({ KafkaReceiver.class, KafkaSender.class }) @ConditionalOnBean(KafkaProperties.class) @EnableConfigurationProperties(ReactiveKafkaProperties.class) public class ReactiveKafkaAutoConfiguration { - private final KafkaProperties kafkaProperties; - private final ReactiveKafkaProperties reactiveKafkaProperties; - public ReactiveKafkaAutoConfiguration(KafkaProperties kafkaProperties, ReactiveKafkaProperties reactiveKafkaProperties) { - this.kafkaProperties = kafkaProperties; - this.reactiveKafkaProperties = reactiveKafkaProperties; - } + private final KafkaProperties kafkaProperties; - @Bean - @ConditionalOnMissingBean(ReceiverOptions.class) - public ReceiverOptions receiverOptions() { - Map properties = kafkaProperties.buildConsumerProperties(); - properties.putAll(this.reactiveKafkaProperties.buildReceiverProperties()); - ReceiverOptions receiverOptions = ReceiverOptions.create(properties); - int atmostOnceCommitAheadSize = this.reactiveKafkaProperties.getReceiver().getAtmostOnceCommitAheadSize(); - if (atmostOnceCommitAheadSize >= 0) { - receiverOptions = receiverOptions.atmostOnceCommitAheadSize(atmostOnceCommitAheadSize); - } - Optional closeTimeout = Optional.ofNullable(this.reactiveKafkaProperties.getReceiver().getCloseTimeout()); - if (closeTimeout.isPresent()) { - receiverOptions = receiverOptions.closeTimeout(closeTimeout.get()); - } - Optional pollTimeout = Optional.ofNullable(this.reactiveKafkaProperties.getReceiver().getPollTimeout()); + private final ReactiveKafkaProperties reactiveKafkaProperties; + + public ReactiveKafkaAutoConfiguration(KafkaProperties kafkaProperties, + ReactiveKafkaProperties reactiveKafkaProperties) { + this.kafkaProperties = kafkaProperties; + this.reactiveKafkaProperties = reactiveKafkaProperties; + } + + @Bean + @ConditionalOnMissingBean(ReceiverOptions.class) + public ReceiverOptions receiverOptions() { + Map properties = kafkaProperties.buildConsumerProperties(); + properties.putAll(this.reactiveKafkaProperties.buildReceiverProperties()); + ReceiverOptions receiverOptions = ReceiverOptions.create(properties); + int atmostOnceCommitAheadSize = this.reactiveKafkaProperties.getReceiver().getAtmostOnceCommitAheadSize(); + if (atmostOnceCommitAheadSize >= 0) { + receiverOptions = receiverOptions.atmostOnceCommitAheadSize(atmostOnceCommitAheadSize); + } + Optional closeTimeout = Optional + .ofNullable(this.reactiveKafkaProperties.getReceiver().getCloseTimeout()); + if (closeTimeout.isPresent()) { + receiverOptions = receiverOptions.closeTimeout(closeTimeout.get()); + } + Optional pollTimeout = Optional + .ofNullable(this.reactiveKafkaProperties.getReceiver().getPollTimeout()); if (pollTimeout.isPresent()) { receiverOptions = receiverOptions.pollTimeout(pollTimeout.get()); } - int maxDeferredCommits = this.reactiveKafkaProperties.getReceiver().getMaxDeferredCommits(); - if (maxDeferredCommits >= 0) { - receiverOptions = receiverOptions.maxDeferredCommits(maxDeferredCommits); - } - int maxCommitAttempts = this.reactiveKafkaProperties.getReceiver().getMaxCommitAttempts(); - if (maxCommitAttempts >= 0) { - receiverOptions = receiverOptions.maxCommitAttempts(maxCommitAttempts); - } - int commitBatchSize = this.reactiveKafkaProperties.getReceiver().getCommitBatchSize(); - if (commitBatchSize >= 0) { - receiverOptions = receiverOptions.commitBatchSize(commitBatchSize); - } - Duration commitInterval = this.reactiveKafkaProperties.getReceiver().getCommitInterval(); - if (commitInterval != null) { - receiverOptions = receiverOptions.commitInterval(commitInterval); - } - Collection subscribeTopics = this.reactiveKafkaProperties.getReceiver().getSubscribeTopics(); - if (subscribeTopics != null) { - receiverOptions = receiverOptions.subscription(subscribeTopics); - } else { - Pattern subscribePattern = this.reactiveKafkaProperties.getReceiver().getSubscribePattern(); - if (subscribePattern != null) { - receiverOptions = receiverOptions.subscription(subscribePattern); - } - } - return receiverOptions; - } + int maxDeferredCommits = this.reactiveKafkaProperties.getReceiver().getMaxDeferredCommits(); + if (maxDeferredCommits >= 0) { + receiverOptions = receiverOptions.maxDeferredCommits(maxDeferredCommits); + } + int maxCommitAttempts = this.reactiveKafkaProperties.getReceiver().getMaxCommitAttempts(); + if (maxCommitAttempts >= 0) { + receiverOptions = receiverOptions.maxCommitAttempts(maxCommitAttempts); + } + int commitBatchSize = this.reactiveKafkaProperties.getReceiver().getCommitBatchSize(); + if (commitBatchSize >= 0) { + receiverOptions = receiverOptions.commitBatchSize(commitBatchSize); + } + Duration commitInterval = this.reactiveKafkaProperties.getReceiver().getCommitInterval(); + if (commitInterval != null) { + receiverOptions = receiverOptions.commitInterval(commitInterval); + } + Collection subscribeTopics = this.reactiveKafkaProperties.getReceiver().getSubscribeTopics(); + if (subscribeTopics != null) { + receiverOptions = receiverOptions.subscription(subscribeTopics); + } + else { + Pattern subscribePattern = this.reactiveKafkaProperties.getReceiver().getSubscribePattern(); + if (subscribePattern != null) { + receiverOptions = receiverOptions.subscription(subscribePattern); + } + } + return receiverOptions; + } + + @Bean + @ConditionalOnMissingBean(SenderOptions.class) + public SenderOptions senderOptions() { + Map properties = kafkaProperties.buildProducerProperties(); + properties.putAll(this.reactiveKafkaProperties.buildSenderProperties()); + SenderOptions senderOptions = SenderOptions.create(properties); + Duration closeTimeout = this.reactiveKafkaProperties.getSender().getCloseTimeout(); + if (closeTimeout != null) { + senderOptions = senderOptions.closeTimeout(closeTimeout); + } + int maxInFlight = this.reactiveKafkaProperties.getSender().getMaxInFlight(); + if (maxInFlight >= 0) { + senderOptions = senderOptions.maxInFlight(maxInFlight); + } + senderOptions = senderOptions.stopOnError(this.reactiveKafkaProperties.getSender().isStopOnError()); + return senderOptions; + } - @Bean - @ConditionalOnMissingBean(SenderOptions.class) - public SenderOptions senderOptions() { - Map properties = kafkaProperties.buildProducerProperties(); - properties.putAll(this.reactiveKafkaProperties.buildSenderProperties()); - SenderOptions senderOptions = SenderOptions.create(properties); - Duration closeTimeout = this.reactiveKafkaProperties.getSender().getCloseTimeout(); - if (closeTimeout != null) { - senderOptions = senderOptions.closeTimeout(closeTimeout); - } - int maxInFlight = this.reactiveKafkaProperties.getSender().getMaxInFlight(); - if (maxInFlight >= 0) { - senderOptions = senderOptions.maxInFlight(maxInFlight); - } - senderOptions = senderOptions.stopOnError(this.reactiveKafkaProperties.getSender().isStopOnError()); - return senderOptions; - } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java index 636adcbbf007..0bedf48d4374 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java @@ -39,295 +39,300 @@ */ @ConfigurationProperties(prefix = "spring.reactor.kafka") public class ReactiveKafkaProperties { - /** - * Additional properties, common to producers and consumers, used to configure the - * client. - */ - private final Map properties = new HashMap<>(); - - private final Receiver receiver = new Receiver(); - - private final Sender sender = new Sender(); - - public Map getProperties() { - return this.properties; - } - - public Receiver getReceiver() { - return this.receiver; - } - - public Sender getSender() { - return this.sender; - } - - - private Map buildCommonProperties() { - Map commonProperties = new HashMap<>(); - if (!CollectionUtils.isEmpty(this.properties)) { - commonProperties.putAll(this.properties); - } - return commonProperties; - } - - /** - * Create an initial map of consumer properties from the state of this instance. - *

- * This allows you to add additional properties, if necessary, and override the - * default kafkaReceiver bean. - * - * @return the consumer properties initialized with the customizations defined on this - * instance - */ - public Map buildReceiverProperties() { - Map receiverProperties = buildCommonProperties(); - receiverProperties.putAll(this.receiver.buildProperties()); - return receiverProperties; - } - - /** - * Create an initial map of producer properties from the state of this instance. - * This allows you to add additional properties, if necessary, and override the - * default kafkaSender bean. - * - * @return the producer properties initialized with the customizations defined on this - * instance - */ - public Map buildSenderProperties() { - Map senderProperties = buildCommonProperties(); - senderProperties.putAll(this.sender.buildProperties()); - return senderProperties; - } - - - public static class Receiver { - /** - * Sets the timeout for each {@link KafkaConsumer#poll(Duration)} operation. Since - * the underlying Kafka consumer is not thread-safe, long poll intervals may delay - * commits and other operations invoked using {@link KafkaReceiver#doOnConsumer(java.util.function.Function)}. - * Very short timeouts may reduce batching and increase load on the broker. - */ - private Duration pollTimeout; - - /** - * Sets timeout for graceful shutdown of {@link KafkaConsumer}. - */ - private Duration closeTimeout; - - /** - * Sets subscription using group management to the specified collection of topics. - */ - private Collection subscribeTopics; - - /** - * Sets subscription using group management to the specified pattern. - */ - private Pattern subscribePattern; - - /** - * Configures commit interval for automatic commits. At least one commit operation is - * attempted within this interval if records are consumed and acknowledged. - */ - private Duration commitInterval; - - - /** - * Configures commit batch size for automatic commits. At least one commit operation is - * attempted when the number of acknowledged uncommitted offsets reaches this batch size. - */ - private int commitBatchSize; - - /** - * Configures commit ahead size per partition for at-most-once delivery. Before dispatching - * each record, an offset ahead by this size may be committed. The maximum number - * of records that may be lost if the application fails is commitAheadSize + 1. - */ - private int atmostOnceCommitAheadSize; - - /** - * Configures the maximum number of consecutive non-fatal {@link RetriableCommitFailedException} - * commit failures that are tolerated. For manual commits, failure in commit after the configured - * number of attempts fails the commit operation. For auto commits, the received Flux is terminated - * if the commit does not succeed after these attempts. - */ - private int maxCommitAttempts; - - /** - * Set to greater than 0 to enable out of order commit sequencing. If the number of - * deferred commits exceeds this value, the consumer is paused until the deferred - * commits are reduced. - */ - private int maxDeferredCommits; - - public Duration getPollTimeout() { - return pollTimeout; - } - - public void setPollTimeout(Duration pollTimeout) { - this.pollTimeout = pollTimeout; - } - - public Duration getCloseTimeout() { - return closeTimeout; - } - - public void setCloseTimeout(Duration closeTimeout) { - this.closeTimeout = closeTimeout; - } - - public Collection getSubscribeTopics() { - return subscribeTopics; - } - - public void setSubscribeTopics(Collection subscribeTopics) { - this.subscribeTopics = subscribeTopics; - } - - public Pattern getSubscribePattern() { - return subscribePattern; - } - - public void setSubscribePattern(Pattern subscribePattern) { - this.subscribePattern = subscribePattern; - } - - public Duration getCommitInterval() { - return commitInterval; - } - - public void setCommitInterval(Duration commitInterval) { - this.commitInterval = commitInterval; - } - - public int getCommitBatchSize() { - return commitBatchSize; - } - - public void setCommitBatchSize(int commitBatchSize) { - this.commitBatchSize = commitBatchSize; - } - - public int getAtmostOnceCommitAheadSize() { - return atmostOnceCommitAheadSize; - } - - public void setAtmostOnceCommitAheadSize(int atmostOnceCommitAheadSize) { - this.atmostOnceCommitAheadSize = atmostOnceCommitAheadSize; - } - - public int getMaxCommitAttempts() { - return maxCommitAttempts; - } - - public void setMaxCommitAttempts(int maxCommitAttempts) { - this.maxCommitAttempts = maxCommitAttempts; - } - - public int getMaxDeferredCommits() { - return maxDeferredCommits; - } - - public void setMaxDeferredCommits(int maxDeferredCommits) { - this.maxDeferredCommits = maxDeferredCommits; - } - - public Map buildProperties() { - Properties receiverProperties = new Properties(); - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(this::getPollTimeout).asInt(Duration::toMillis).to(receiverProperties.in("pollTimeout")); - map.from(this::getCloseTimeout).asInt(Duration::toMillis).to(receiverProperties.in("closeTimeout")); - map.from(this::getCommitInterval).asInt(Duration::toMillis).to(receiverProperties.in("commitInterval")); - map.from(this::getCommitBatchSize).to(receiverProperties.in("commitBatchSize")); - map.from(this::getAtmostOnceCommitAheadSize).to(receiverProperties.in("atmostOnceCommitAheadSize")); - map.from(this::getMaxCommitAttempts).to(receiverProperties.in("maxCommitAttempts")); - map.from(this::getMaxDeferredCommits).to(receiverProperties.in("maxDeferredCommits")); - map.from(this::getSubscribeTopics).to(receiverProperties.in("subscribeTopics")); - map.from(this::getSubscribePattern).to(receiverProperties.in("subscribePattern")); - return receiverProperties; - } - } - - public static class Sender { - - private final Map properties = new HashMap<>(); - - /** - * Configures the maximum number of in-flight records that are fetched - * from the outbound record publisher while acknowledgements are pending. - * This limit must be configured along with {@link ProducerConfig#BUFFER_MEMORY_CONFIG} - * to control memory usage and to avoid blocking the reactive pipeline. - */ - private int maxInFlight; - - - /** - * Configures error handling behaviour for {@link reactor.kafka.sender.KafkaSender#send(org.reactivestreams.Publisher)}. - * If set to true, send fails when an error is encountered and only records - * that are already in transit may be delivered after the first error. If set to false, - * an attempt is made to send each record to Kafka, even if one or more records cannot - * be delivered after the configured number of retries due to a non-fatal exception. - * This flag should be set along with {@link ProducerConfig#RETRIES_CONFIG} and - * {@link ProducerConfig#ACKS_CONFIG} to configure the required quality-of-service. - * By default, stopOnError is true. - */ - private boolean stopOnError; - - /** - * Configures the timeout for graceful shutdown of this sender. - */ - private Duration closeTimeout; - - public int getMaxInFlight() { - return maxInFlight; - } - - public void setMaxInFlight(int maxInFlight) { - this.maxInFlight = maxInFlight; - } - - public boolean isStopOnError() { - return stopOnError; - } - - public void setStopOnError(boolean stopOnError) { - this.stopOnError = stopOnError; - } - - public Duration getCloseTimeout() { - return closeTimeout; - } - - public void setCloseTimeout(Duration closeTimeout) { - this.closeTimeout = closeTimeout; - } - - public Map getProperties() { - return this.properties; - } - - public Map buildProperties() { - Properties senderProperties = new Properties(); - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(this::getCloseTimeout).asInt(Duration::toMillis).to(senderProperties.in("closeTimeout")); - map.from(this::isStopOnError).to(senderProperties.in("stopOnError")); - map.from(this::getMaxInFlight).to(senderProperties.in("maxInFlight")); - return senderProperties; - } - } - - @SuppressWarnings("serial") - public static class Properties extends HashMap { - - public java.util.function.Consumer in(String key) { - return (value) -> put(key, value); - } - - public Properties with(KafkaProperties.Ssl ssl, KafkaProperties.Security security, Map properties) { - putAll(ssl.buildProperties()); - putAll(security.buildProperties()); - putAll(properties); - return this; - } - - } + + /** + * Additional properties, common to producers and consumers, used to configure the + * client. + */ + private final Map properties = new HashMap<>(); + + private final Receiver receiver = new Receiver(); + + private final Sender sender = new Sender(); + + public Map getProperties() { + return this.properties; + } + + public Receiver getReceiver() { + return this.receiver; + } + + public Sender getSender() { + return this.sender; + } + + private Map buildCommonProperties() { + Map commonProperties = new HashMap<>(); + if (!CollectionUtils.isEmpty(this.properties)) { + commonProperties.putAll(this.properties); + } + return commonProperties; + } + + /** + * Create an initial map of consumer properties from the state of this instance. + *

+ * This allows you to add additional properties, if necessary, and override the + * default kafkaReceiver bean. + * @return the consumer properties initialized with the customizations defined on this + * instance + */ + public Map buildReceiverProperties() { + Map receiverProperties = buildCommonProperties(); + receiverProperties.putAll(this.receiver.buildProperties()); + return receiverProperties; + } + + /** + * Create an initial map of producer properties from the state of this instance. This + * allows you to add additional properties, if necessary, and override the default + * kafkaSender bean. + * @return the producer properties initialized with the customizations defined on this + * instance + */ + public Map buildSenderProperties() { + Map senderProperties = buildCommonProperties(); + senderProperties.putAll(this.sender.buildProperties()); + return senderProperties; + } + + public static class Receiver { + + /** + * Sets the timeout for each {@link KafkaConsumer#poll(Duration)} operation. Since + * the underlying Kafka consumer is not thread-safe, long poll intervals may delay + * commits and other operations invoked using + * {@link KafkaReceiver#doOnConsumer(java.util.function.Function)}. Very short + * timeouts may reduce batching and increase load on the broker. + */ + private Duration pollTimeout; + + /** + * Sets timeout for graceful shutdown of {@link KafkaConsumer}. + */ + private Duration closeTimeout; + + /** + * Sets subscription using group management to the specified collection of topics. + */ + private Collection subscribeTopics; + + /** + * Sets subscription using group management to the specified pattern. + */ + private Pattern subscribePattern; + + /** + * Configures commit interval for automatic commits. At least one commit operation + * is attempted within this interval if records are consumed and acknowledged. + */ + private Duration commitInterval; + + /** + * Configures commit batch size for automatic commits. At least one commit + * operation is attempted when the number of acknowledged uncommitted offsets + * reaches this batch size. + */ + private int commitBatchSize; + + /** + * Configures commit ahead size per partition for at-most-once delivery. Before + * dispatching each record, an offset ahead by this size may be committed. The + * maximum number of records that may be lost if the application fails is + * commitAheadSize + 1. + */ + private int atmostOnceCommitAheadSize; + + /** + * Configures the maximum number of consecutive non-fatal + * {@link RetriableCommitFailedException} commit failures that are tolerated. For + * manual commits, failure in commit after the configured number of attempts fails + * the commit operation. For auto commits, the received Flux is terminated if the + * commit does not succeed after these attempts. + */ + private int maxCommitAttempts; + + /** + * Set to greater than 0 to enable out of order commit sequencing. If the number + * of deferred commits exceeds this value, the consumer is paused until the + * deferred commits are reduced. + */ + private int maxDeferredCommits; + + public Duration getPollTimeout() { + return pollTimeout; + } + + public void setPollTimeout(Duration pollTimeout) { + this.pollTimeout = pollTimeout; + } + + public Duration getCloseTimeout() { + return closeTimeout; + } + + public void setCloseTimeout(Duration closeTimeout) { + this.closeTimeout = closeTimeout; + } + + public Collection getSubscribeTopics() { + return subscribeTopics; + } + + public void setSubscribeTopics(Collection subscribeTopics) { + this.subscribeTopics = subscribeTopics; + } + + public Pattern getSubscribePattern() { + return subscribePattern; + } + + public void setSubscribePattern(Pattern subscribePattern) { + this.subscribePattern = subscribePattern; + } + + public Duration getCommitInterval() { + return commitInterval; + } + + public void setCommitInterval(Duration commitInterval) { + this.commitInterval = commitInterval; + } + + public int getCommitBatchSize() { + return commitBatchSize; + } + + public void setCommitBatchSize(int commitBatchSize) { + this.commitBatchSize = commitBatchSize; + } + + public int getAtmostOnceCommitAheadSize() { + return atmostOnceCommitAheadSize; + } + + public void setAtmostOnceCommitAheadSize(int atmostOnceCommitAheadSize) { + this.atmostOnceCommitAheadSize = atmostOnceCommitAheadSize; + } + + public int getMaxCommitAttempts() { + return maxCommitAttempts; + } + + public void setMaxCommitAttempts(int maxCommitAttempts) { + this.maxCommitAttempts = maxCommitAttempts; + } + + public int getMaxDeferredCommits() { + return maxDeferredCommits; + } + + public void setMaxDeferredCommits(int maxDeferredCommits) { + this.maxDeferredCommits = maxDeferredCommits; + } + + public Map buildProperties() { + Properties receiverProperties = new Properties(); + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + map.from(this::getPollTimeout).asInt(Duration::toMillis).to(receiverProperties.in("pollTimeout")); + map.from(this::getCloseTimeout).asInt(Duration::toMillis).to(receiverProperties.in("closeTimeout")); + map.from(this::getCommitInterval).asInt(Duration::toMillis).to(receiverProperties.in("commitInterval")); + map.from(this::getCommitBatchSize).to(receiverProperties.in("commitBatchSize")); + map.from(this::getAtmostOnceCommitAheadSize).to(receiverProperties.in("atmostOnceCommitAheadSize")); + map.from(this::getMaxCommitAttempts).to(receiverProperties.in("maxCommitAttempts")); + map.from(this::getMaxDeferredCommits).to(receiverProperties.in("maxDeferredCommits")); + map.from(this::getSubscribeTopics).to(receiverProperties.in("subscribeTopics")); + map.from(this::getSubscribePattern).to(receiverProperties.in("subscribePattern")); + return receiverProperties; + } + + } + + public static class Sender { + + private final Map properties = new HashMap<>(); + + /** + * Configures the maximum number of in-flight records that are fetched from the + * outbound record publisher while acknowledgements are pending. This limit must + * be configured along with {@link ProducerConfig#BUFFER_MEMORY_CONFIG} to control + * memory usage and to avoid blocking the reactive pipeline. + */ + private int maxInFlight; + + /** + * Configures error handling behaviour for + * {@link reactor.kafka.sender.KafkaSender#send(org.reactivestreams.Publisher)}. + * If set to true, send fails when an error is encountered and only records that + * are already in transit may be delivered after the first error. If set to false, + * an attempt is made to send each record to Kafka, even if one or more records + * cannot be delivered after the configured number of retries due to a non-fatal + * exception. This flag should be set along with + * {@link ProducerConfig#RETRIES_CONFIG} and {@link ProducerConfig#ACKS_CONFIG} to + * configure the required quality-of-service. By default, stopOnError is true. + */ + private boolean stopOnError; + + /** + * Configures the timeout for graceful shutdown of this sender. + */ + private Duration closeTimeout; + + public int getMaxInFlight() { + return maxInFlight; + } + + public void setMaxInFlight(int maxInFlight) { + this.maxInFlight = maxInFlight; + } + + public boolean isStopOnError() { + return stopOnError; + } + + public void setStopOnError(boolean stopOnError) { + this.stopOnError = stopOnError; + } + + public Duration getCloseTimeout() { + return closeTimeout; + } + + public void setCloseTimeout(Duration closeTimeout) { + this.closeTimeout = closeTimeout; + } + + public Map getProperties() { + return this.properties; + } + + public Map buildProperties() { + Properties senderProperties = new Properties(); + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + map.from(this::getCloseTimeout).asInt(Duration::toMillis).to(senderProperties.in("closeTimeout")); + map.from(this::isStopOnError).to(senderProperties.in("stopOnError")); + map.from(this::getMaxInFlight).to(senderProperties.in("maxInFlight")); + return senderProperties; + } + + } + + @SuppressWarnings("serial") + public static class Properties extends HashMap { + + public java.util.function.Consumer in(String key) { + return (value) -> put(key, value); + } + + public Properties with(KafkaProperties.Ssl ssl, KafkaProperties.Security security, + Map properties) { + putAll(ssl.buildProperties()); + putAll(security.buildProperties()); + putAll(properties); + return this; + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java index 9ddcde65100c..ec13848d42e2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java @@ -35,47 +35,48 @@ * @author Almog Tavor */ class ReactiveKafkaAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(KafkaAutoConfiguration.class)) - .withConfiguration(AutoConfigurations.of(ReactiveKafkaAutoConfiguration.class)); - @Test - void receiverProperties() { - this.contextRunner.withPropertyValues( - "spring.reactor.kafka.receiver.commit-interval=2000", "spring.reactor.kafka.receiver.close-timeout=1500", - "spring.reactor.kafka.receiver.commit-batch-size=100", "spring.reactor.kafka.receiver.poll-timeout=1000", - "spring.reactor.kafka.receiver.atmost-once-commit-ahead-size=42", "spring.reactor.kafka.receiver.max-commit-attempts=3", - "spring.reactor.kafka.receiver.max-deferred-commits=5", "spring.reactor.kafka.receiver.subscribe-topics=foo,bar", - "spring.reactor.kafka.receiver.subscribe-pattern=myTopic.+") - .run((context) -> { - ReceiverOptions receiverOptions = context - .getBean(ReceiverOptions.class); - Map configs = receiverOptions.consumerProperties(); - assertThat(configs.get("commitInterval")).isEqualTo(2000); - assertThat(configs.get("closeTimeout")).isEqualTo(1500); - assertThat(configs.get("commitBatchSize")).isEqualTo(100); - assertThat(configs.get("pollTimeout")).isEqualTo(1000); - assertThat(configs.get("atmostOnceCommitAheadSize")).isEqualTo(42); - assertThat(configs.get("maxCommitAttempts")).isEqualTo(3); - assertThat(configs.get("maxDeferredCommits")).isEqualTo(5); - assertThat(configs.get("subscribeTopics")).isEqualTo(Arrays.asList("foo", "bar")); - assertThat((Pattern) configs.get("subscribePattern")) - .matches(p -> Objects.equals(Pattern.compile("myTopic.+").pattern(), p.pattern())); - }); - } + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(KafkaAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(ReactiveKafkaAutoConfiguration.class)); + + @Test + void receiverProperties() { + this.contextRunner.withPropertyValues("spring.reactor.kafka.receiver.commit-interval=2000", + "spring.reactor.kafka.receiver.close-timeout=1500", + "spring.reactor.kafka.receiver.commit-batch-size=100", + "spring.reactor.kafka.receiver.poll-timeout=1000", + "spring.reactor.kafka.receiver.atmost-once-commit-ahead-size=42", + "spring.reactor.kafka.receiver.max-commit-attempts=3", + "spring.reactor.kafka.receiver.max-deferred-commits=5", + "spring.reactor.kafka.receiver.subscribe-topics=foo,bar", + "spring.reactor.kafka.receiver.subscribe-pattern=myTopic.+").run((context) -> { + ReceiverOptions receiverOptions = context.getBean(ReceiverOptions.class); + Map configs = receiverOptions.consumerProperties(); + assertThat(configs.get("commitInterval")).isEqualTo(2000); + assertThat(configs.get("closeTimeout")).isEqualTo(1500); + assertThat(configs.get("commitBatchSize")).isEqualTo(100); + assertThat(configs.get("pollTimeout")).isEqualTo(1000); + assertThat(configs.get("atmostOnceCommitAheadSize")).isEqualTo(42); + assertThat(configs.get("maxCommitAttempts")).isEqualTo(3); + assertThat(configs.get("maxDeferredCommits")).isEqualTo(5); + assertThat(configs.get("subscribeTopics")).isEqualTo(Arrays.asList("foo", "bar")); + assertThat((Pattern) configs.get("subscribePattern")) + .matches(p -> Objects.equals(Pattern.compile("myTopic.+").pattern(), p.pattern())); + }); + } + + @Test + void producerProperties() { + this.contextRunner.withPropertyValues("spring.reactor.kafka.sender.max-in-flight=1500", + "spring.reactor.kafka.sender.stop-on-error=false", "spring.reactor.kafka.sender.close-timeout=500") + .run((context) -> { + SenderOptions senderOptions = context.getBean(SenderOptions.class); + Map configs = senderOptions.producerProperties(); + assertThat(configs.get("maxInFlight")).isEqualTo(1500); + assertThat((Boolean) configs.get("stopOnError")).isFalse(); + assertThat(configs.get("closeTimeout")).isEqualTo(500); + }); + } - @Test - void producerProperties() { - this.contextRunner.withPropertyValues( - "spring.reactor.kafka.sender.max-in-flight=1500", "spring.reactor.kafka.sender.stop-on-error=false", - "spring.reactor.kafka.sender.close-timeout=500") - .run((context) -> { - SenderOptions senderOptions = context - .getBean(SenderOptions.class); - Map configs = senderOptions.producerProperties(); - assertThat(configs.get("maxInFlight")).isEqualTo(1500); - assertThat((Boolean) configs.get("stopOnError")).isFalse(); - assertThat(configs.get("closeTimeout")).isEqualTo(500); - }); - } } From ff8f2658501f68502127028f1c0cd51a1199e681 Mon Sep 17 00:00:00 2001 From: Almog Tavor Date: Fri, 8 Apr 2022 20:21:09 +0300 Subject: [PATCH 04/12] Fix: checkstyle notes --- .../kafka/ReactiveKafkaAutoConfiguration.java | 26 +++++++------- .../kafka/ReactiveKafkaProperties.java | 36 ++++++++++--------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java index 97a554fe8b2f..1814586d85a6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java @@ -16,6 +16,18 @@ package org.springframework.boot.autoconfigure.kafka; + +import java.time.Duration; +import java.util.Collection; +import java.util.Map; +import java.util.Optional; +import java.util.regex.Pattern; + +import reactor.kafka.receiver.KafkaReceiver; +import reactor.kafka.receiver.ReceiverOptions; +import reactor.kafka.sender.KafkaSender; +import reactor.kafka.sender.SenderOptions; + import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -23,16 +35,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; -import reactor.kafka.receiver.KafkaReceiver; -import reactor.kafka.receiver.ReceiverOptions; -import reactor.kafka.sender.KafkaSender; -import reactor.kafka.sender.SenderOptions; - -import java.time.Duration; -import java.util.Collection; -import java.util.Map; -import java.util.Optional; -import java.util.regex.Pattern; /** * {@link EnableAutoConfiguration Auto-configuration} for the Reactive client of Apache @@ -60,7 +62,7 @@ public ReactiveKafkaAutoConfiguration(KafkaProperties kafkaProperties, @Bean @ConditionalOnMissingBean(ReceiverOptions.class) public ReceiverOptions receiverOptions() { - Map properties = kafkaProperties.buildConsumerProperties(); + Map properties = this.kafkaProperties.buildConsumerProperties(); properties.putAll(this.reactiveKafkaProperties.buildReceiverProperties()); ReceiverOptions receiverOptions = ReceiverOptions.create(properties); int atmostOnceCommitAheadSize = this.reactiveKafkaProperties.getReceiver().getAtmostOnceCommitAheadSize(); @@ -109,7 +111,7 @@ public ReceiverOptions receiverOptions() { @Bean @ConditionalOnMissingBean(SenderOptions.class) public SenderOptions senderOptions() { - Map properties = kafkaProperties.buildProducerProperties(); + Map properties = this.kafkaProperties.buildProducerProperties(); properties.putAll(this.reactiveKafkaProperties.buildSenderProperties()); SenderOptions senderOptions = SenderOptions.create(properties); Duration closeTimeout = this.reactiveKafkaProperties.getSender().getCloseTimeout(); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java index 0bedf48d4374..21b17da1a5b3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java @@ -16,17 +16,21 @@ package org.springframework.boot.autoconfigure.kafka; +import java.time.Duration; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; + import org.apache.kafka.clients.consumer.KafkaConsumer; import org.apache.kafka.clients.consumer.RetriableCommitFailedException; import org.apache.kafka.clients.producer.ProducerConfig; +import reactor.kafka.receiver.KafkaReceiver; + import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.util.CollectionUtils; -import reactor.kafka.receiver.KafkaReceiver; -import java.time.Duration; -import java.util.*; -import java.util.regex.Pattern; /** * Configuration properties for Project Reactor for Apache Kafka. @@ -161,7 +165,7 @@ public static class Receiver { private int maxDeferredCommits; public Duration getPollTimeout() { - return pollTimeout; + return this.pollTimeout; } public void setPollTimeout(Duration pollTimeout) { @@ -169,7 +173,7 @@ public void setPollTimeout(Duration pollTimeout) { } public Duration getCloseTimeout() { - return closeTimeout; + return this.closeTimeout; } public void setCloseTimeout(Duration closeTimeout) { @@ -177,7 +181,7 @@ public void setCloseTimeout(Duration closeTimeout) { } public Collection getSubscribeTopics() { - return subscribeTopics; + return this.subscribeTopics; } public void setSubscribeTopics(Collection subscribeTopics) { @@ -185,7 +189,7 @@ public void setSubscribeTopics(Collection subscribeTopics) { } public Pattern getSubscribePattern() { - return subscribePattern; + return this.subscribePattern; } public void setSubscribePattern(Pattern subscribePattern) { @@ -193,7 +197,7 @@ public void setSubscribePattern(Pattern subscribePattern) { } public Duration getCommitInterval() { - return commitInterval; + return this.commitInterval; } public void setCommitInterval(Duration commitInterval) { @@ -201,7 +205,7 @@ public void setCommitInterval(Duration commitInterval) { } public int getCommitBatchSize() { - return commitBatchSize; + return this.commitBatchSize; } public void setCommitBatchSize(int commitBatchSize) { @@ -209,7 +213,7 @@ public void setCommitBatchSize(int commitBatchSize) { } public int getAtmostOnceCommitAheadSize() { - return atmostOnceCommitAheadSize; + return this.atmostOnceCommitAheadSize; } public void setAtmostOnceCommitAheadSize(int atmostOnceCommitAheadSize) { @@ -217,7 +221,7 @@ public void setAtmostOnceCommitAheadSize(int atmostOnceCommitAheadSize) { } public int getMaxCommitAttempts() { - return maxCommitAttempts; + return this.maxCommitAttempts; } public void setMaxCommitAttempts(int maxCommitAttempts) { @@ -225,7 +229,7 @@ public void setMaxCommitAttempts(int maxCommitAttempts) { } public int getMaxDeferredCommits() { - return maxDeferredCommits; + return this.maxDeferredCommits; } public void setMaxDeferredCommits(int maxDeferredCommits) { @@ -280,7 +284,7 @@ public static class Sender { private Duration closeTimeout; public int getMaxInFlight() { - return maxInFlight; + return this.maxInFlight; } public void setMaxInFlight(int maxInFlight) { @@ -288,7 +292,7 @@ public void setMaxInFlight(int maxInFlight) { } public boolean isStopOnError() { - return stopOnError; + return this.stopOnError; } public void setStopOnError(boolean stopOnError) { @@ -296,7 +300,7 @@ public void setStopOnError(boolean stopOnError) { } public Duration getCloseTimeout() { - return closeTimeout; + return this.closeTimeout; } public void setCloseTimeout(Duration closeTimeout) { From e8d254785ac13be97279c0c5eac3c7162b32d453 Mon Sep 17 00:00:00 2001 From: Almog Tavor Date: Fri, 8 Apr 2022 20:51:27 +0300 Subject: [PATCH 05/12] Fix: checkstyle notes --- .../ReactiveKafkaAutoConfigurationTests.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java index ec13848d42e2..b4c9546e9c38 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java @@ -16,17 +16,18 @@ package org.springframework.boot.autoconfigure.kafka; -import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import reactor.kafka.receiver.ReceiverOptions; -import reactor.kafka.sender.SenderOptions; - import java.util.Arrays; import java.util.Map; import java.util.Objects; import java.util.regex.Pattern; +import org.junit.jupiter.api.Test; +import reactor.kafka.receiver.ReceiverOptions; +import reactor.kafka.sender.SenderOptions; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + import static org.assertj.core.api.Assertions.assertThat; /** @@ -62,7 +63,7 @@ void receiverProperties() { assertThat(configs.get("maxDeferredCommits")).isEqualTo(5); assertThat(configs.get("subscribeTopics")).isEqualTo(Arrays.asList("foo", "bar")); assertThat((Pattern) configs.get("subscribePattern")) - .matches(p -> Objects.equals(Pattern.compile("myTopic.+").pattern(), p.pattern())); + .matches((p) -> Objects.equals(Pattern.compile("myTopic.+").pattern(), p.pattern())); }); } From e2a3023b3457b57c4d4cc8ab3a22cbf3c8b1a897 Mon Sep 17 00:00:00 2001 From: Almog Tavor Date: Fri, 8 Apr 2022 21:36:41 +0300 Subject: [PATCH 06/12] Fix: formatting --- .../boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java | 1 - .../boot/autoconfigure/kafka/ReactiveKafkaProperties.java | 1 - 2 files changed, 2 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java index 1814586d85a6..5cce879ed202 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java @@ -16,7 +16,6 @@ package org.springframework.boot.autoconfigure.kafka; - import java.time.Duration; import java.util.Collection; import java.util.Map; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java index 21b17da1a5b3..d51ef61e2592 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java @@ -31,7 +31,6 @@ import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.util.CollectionUtils; - /** * Configuration properties for Project Reactor for Apache Kafka. *

From abe59b4d9fbbd681b7b134d3f433383b3cdf03bd Mon Sep 17 00:00:00 2001 From: Almog Tavor Date: Wed, 20 Apr 2022 17:38:15 +0300 Subject: [PATCH 07/12] Fix: no preperies bug, remove redundant code and mapper migration --- .../kafka/ReactiveKafkaAutoConfiguration.java | 114 +++++++----------- .../kafka/ReactiveKafkaProperties.java | 78 +----------- .../ReactiveKafkaAutoConfigurationTests.java | 69 ++++++----- 3 files changed, 93 insertions(+), 168 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java index 5cce879ed202..8fd6bf025b74 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java @@ -16,24 +16,22 @@ package org.springframework.boot.autoconfigure.kafka; -import java.time.Duration; -import java.util.Collection; -import java.util.Map; -import java.util.Optional; -import java.util.regex.Pattern; - -import reactor.kafka.receiver.KafkaReceiver; -import reactor.kafka.receiver.ReceiverOptions; -import reactor.kafka.sender.KafkaSender; -import reactor.kafka.sender.SenderOptions; - import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.context.annotation.Bean; +import reactor.kafka.receiver.KafkaReceiver; +import reactor.kafka.receiver.ReceiverOptions; +import reactor.kafka.sender.KafkaSender; +import reactor.kafka.sender.SenderOptions; + +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; /** * {@link EnableAutoConfiguration Auto-configuration} for the Reactive client of Apache @@ -43,17 +41,15 @@ * @since 2.7.0 */ @AutoConfiguration -@ConditionalOnClass({ KafkaReceiver.class, KafkaSender.class }) +@ConditionalOnClass({KafkaReceiver.class, KafkaSender.class}) @ConditionalOnBean(KafkaProperties.class) @EnableConfigurationProperties(ReactiveKafkaProperties.class) public class ReactiveKafkaAutoConfiguration { - private final KafkaProperties kafkaProperties; - private final ReactiveKafkaProperties reactiveKafkaProperties; + private static final PropertyMapper map = PropertyMapper.get(); - public ReactiveKafkaAutoConfiguration(KafkaProperties kafkaProperties, - ReactiveKafkaProperties reactiveKafkaProperties) { + public ReactiveKafkaAutoConfiguration(KafkaProperties kafkaProperties, ReactiveKafkaProperties reactiveKafkaProperties) { this.kafkaProperties = kafkaProperties; this.reactiveKafkaProperties = reactiveKafkaProperties; } @@ -62,47 +58,18 @@ public ReactiveKafkaAutoConfiguration(KafkaProperties kafkaProperties, @ConditionalOnMissingBean(ReceiverOptions.class) public ReceiverOptions receiverOptions() { Map properties = this.kafkaProperties.buildConsumerProperties(); - properties.putAll(this.reactiveKafkaProperties.buildReceiverProperties()); ReceiverOptions receiverOptions = ReceiverOptions.create(properties); - int atmostOnceCommitAheadSize = this.reactiveKafkaProperties.getReceiver().getAtmostOnceCommitAheadSize(); - if (atmostOnceCommitAheadSize >= 0) { - receiverOptions = receiverOptions.atmostOnceCommitAheadSize(atmostOnceCommitAheadSize); - } - Optional closeTimeout = Optional - .ofNullable(this.reactiveKafkaProperties.getReceiver().getCloseTimeout()); - if (closeTimeout.isPresent()) { - receiverOptions = receiverOptions.closeTimeout(closeTimeout.get()); - } - Optional pollTimeout = Optional - .ofNullable(this.reactiveKafkaProperties.getReceiver().getPollTimeout()); - if (pollTimeout.isPresent()) { - receiverOptions = receiverOptions.pollTimeout(pollTimeout.get()); - } - int maxDeferredCommits = this.reactiveKafkaProperties.getReceiver().getMaxDeferredCommits(); - if (maxDeferredCommits >= 0) { - receiverOptions = receiverOptions.maxDeferredCommits(maxDeferredCommits); - } - int maxCommitAttempts = this.reactiveKafkaProperties.getReceiver().getMaxCommitAttempts(); - if (maxCommitAttempts >= 0) { - receiverOptions = receiverOptions.maxCommitAttempts(maxCommitAttempts); - } - int commitBatchSize = this.reactiveKafkaProperties.getReceiver().getCommitBatchSize(); - if (commitBatchSize >= 0) { - receiverOptions = receiverOptions.commitBatchSize(commitBatchSize); - } - Duration commitInterval = this.reactiveKafkaProperties.getReceiver().getCommitInterval(); - if (commitInterval != null) { - receiverOptions = receiverOptions.commitInterval(commitInterval); - } - Collection subscribeTopics = this.reactiveKafkaProperties.getReceiver().getSubscribeTopics(); - if (subscribeTopics != null) { - receiverOptions = receiverOptions.subscription(subscribeTopics); - } - else { - Pattern subscribePattern = this.reactiveKafkaProperties.getReceiver().getSubscribePattern(); - if (subscribePattern != null) { - receiverOptions = receiverOptions.subscription(subscribePattern); - } + ReactiveKafkaProperties.Receiver receiverProperties = this.reactiveKafkaProperties.getReceiver(); + receiverOptions = setPropertyWhenGreaterThanZero(receiverProperties.getAtmostOnceCommitAheadSize(), receiverOptions::atmostOnceCommitAheadSize, receiverOptions); + receiverOptions = setPropertyWhenGreaterThanZero(receiverProperties.getMaxDeferredCommits(), receiverOptions::maxDeferredCommits, receiverOptions); + receiverOptions = setPropertyWhenGreaterThanZero(receiverProperties.getMaxCommitAttempts(), receiverOptions::maxCommitAttempts, receiverOptions); + receiverOptions = setPropertyWhenGreaterThanZero(receiverProperties.getCommitBatchSize(), receiverOptions::commitBatchSize, receiverOptions); + receiverOptions = setPropertyWhenNonNull(receiverProperties.getCloseTimeout(), receiverOptions::closeTimeout, receiverOptions); + receiverOptions = setPropertyWhenNonNull(receiverProperties.getPollTimeout(), receiverOptions::pollTimeout, receiverOptions); + receiverOptions = setPropertyWhenNonNull(receiverProperties.getCommitInterval(), receiverOptions::commitInterval, receiverOptions); + receiverOptions = setPropertyWhenNonNull(receiverProperties.getSubscribeTopics(), receiverOptions::subscription, receiverOptions); + if (Optional.ofNullable(receiverProperties.getSubscribeTopics()).isEmpty()) { + receiverOptions = setPropertyWhenNonNull(receiverProperties.getSubscribePattern(), receiverOptions::subscription, receiverOptions); } return receiverOptions; } @@ -110,19 +77,30 @@ public ReceiverOptions receiverOptions() { @Bean @ConditionalOnMissingBean(SenderOptions.class) public SenderOptions senderOptions() { - Map properties = this.kafkaProperties.buildProducerProperties(); - properties.putAll(this.reactiveKafkaProperties.buildSenderProperties()); - SenderOptions senderOptions = SenderOptions.create(properties); - Duration closeTimeout = this.reactiveKafkaProperties.getSender().getCloseTimeout(); - if (closeTimeout != null) { - senderOptions = senderOptions.closeTimeout(closeTimeout); - } - int maxInFlight = this.reactiveKafkaProperties.getSender().getMaxInFlight(); - if (maxInFlight >= 0) { - senderOptions = senderOptions.maxInFlight(maxInFlight); - } - senderOptions = senderOptions.stopOnError(this.reactiveKafkaProperties.getSender().isStopOnError()); + Map properties = kafkaProperties.buildProducerProperties(); + SenderOptions senderOptions = SenderOptions.create(properties); + ReactiveKafkaProperties.Sender senderProperties = this.reactiveKafkaProperties.getSender(); + senderOptions = map.from(senderProperties.getCloseTimeout()).toInstance(senderOptions::closeTimeout); + senderOptions = setPropertyWhenGreaterThanZero(senderProperties.getMaxInFlight(), senderOptions::maxInFlight, senderOptions); + senderOptions = map.from(senderProperties.isStopOnError()).toInstance(senderOptions::stopOnError); return senderOptions; } + private T setPropertyWhenGreaterThanZero(Integer property, Function function, T options) { + if (property <= 0) { + return options; + } + return map.from(property) + .when(i -> i > 0) + .toInstance(function); + } + + private T setPropertyWhenNonNull(S property, Function function, T options) { + if (Optional.ofNullable(property).isEmpty()) { + return options; + } + return map.from(property) + .whenNonNull() + .toInstance(function); + } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java index d51ef61e2592..67b08e4e319b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java @@ -16,20 +16,17 @@ package org.springframework.boot.autoconfigure.kafka; -import java.time.Duration; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Pattern; - import org.apache.kafka.clients.consumer.KafkaConsumer; import org.apache.kafka.clients.consumer.RetriableCommitFailedException; import org.apache.kafka.clients.producer.ProducerConfig; +import org.springframework.boot.context.properties.ConfigurationProperties; import reactor.kafka.receiver.KafkaReceiver; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.util.CollectionUtils; +import java.time.Duration; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; /** * Configuration properties for Project Reactor for Apache Kafka. @@ -65,41 +62,6 @@ public Sender getSender() { return this.sender; } - private Map buildCommonProperties() { - Map commonProperties = new HashMap<>(); - if (!CollectionUtils.isEmpty(this.properties)) { - commonProperties.putAll(this.properties); - } - return commonProperties; - } - - /** - * Create an initial map of consumer properties from the state of this instance. - *

- * This allows you to add additional properties, if necessary, and override the - * default kafkaReceiver bean. - * @return the consumer properties initialized with the customizations defined on this - * instance - */ - public Map buildReceiverProperties() { - Map receiverProperties = buildCommonProperties(); - receiverProperties.putAll(this.receiver.buildProperties()); - return receiverProperties; - } - - /** - * Create an initial map of producer properties from the state of this instance. This - * allows you to add additional properties, if necessary, and override the default - * kafkaSender bean. - * @return the producer properties initialized with the customizations defined on this - * instance - */ - public Map buildSenderProperties() { - Map senderProperties = buildCommonProperties(); - senderProperties.putAll(this.sender.buildProperties()); - return senderProperties; - } - public static class Receiver { /** @@ -234,22 +196,6 @@ public int getMaxDeferredCommits() { public void setMaxDeferredCommits(int maxDeferredCommits) { this.maxDeferredCommits = maxDeferredCommits; } - - public Map buildProperties() { - Properties receiverProperties = new Properties(); - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(this::getPollTimeout).asInt(Duration::toMillis).to(receiverProperties.in("pollTimeout")); - map.from(this::getCloseTimeout).asInt(Duration::toMillis).to(receiverProperties.in("closeTimeout")); - map.from(this::getCommitInterval).asInt(Duration::toMillis).to(receiverProperties.in("commitInterval")); - map.from(this::getCommitBatchSize).to(receiverProperties.in("commitBatchSize")); - map.from(this::getAtmostOnceCommitAheadSize).to(receiverProperties.in("atmostOnceCommitAheadSize")); - map.from(this::getMaxCommitAttempts).to(receiverProperties.in("maxCommitAttempts")); - map.from(this::getMaxDeferredCommits).to(receiverProperties.in("maxDeferredCommits")); - map.from(this::getSubscribeTopics).to(receiverProperties.in("subscribeTopics")); - map.from(this::getSubscribePattern).to(receiverProperties.in("subscribePattern")); - return receiverProperties; - } - } public static class Sender { @@ -309,16 +255,6 @@ public void setCloseTimeout(Duration closeTimeout) { public Map getProperties() { return this.properties; } - - public Map buildProperties() { - Properties senderProperties = new Properties(); - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(this::getCloseTimeout).asInt(Duration::toMillis).to(senderProperties.in("closeTimeout")); - map.from(this::isStopOnError).to(senderProperties.in("stopOnError")); - map.from(this::getMaxInFlight).to(senderProperties.in("maxInFlight")); - return senderProperties; - } - } @SuppressWarnings("serial") @@ -335,7 +271,5 @@ public Properties with(KafkaProperties.Ssl ssl, KafkaProperties.Security securit putAll(properties); return this; } - } - } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java index b4c9546e9c38..c56cc940b48d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java @@ -16,17 +16,16 @@ package org.springframework.boot.autoconfigure.kafka; -import java.util.Arrays; -import java.util.Map; -import java.util.Objects; -import java.util.regex.Pattern; - import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; import reactor.kafka.receiver.ReceiverOptions; import reactor.kafka.sender.SenderOptions; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import java.time.Duration; +import java.util.Arrays; +import java.util.Objects; +import java.util.regex.Pattern; import static org.assertj.core.api.Assertions.assertThat; @@ -36,7 +35,6 @@ * @author Almog Tavor */ class ReactiveKafkaAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(KafkaAutoConfiguration.class)) .withConfiguration(AutoConfigurations.of(ReactiveKafkaAutoConfiguration.class)); @@ -50,34 +48,49 @@ void receiverProperties() { "spring.reactor.kafka.receiver.atmost-once-commit-ahead-size=42", "spring.reactor.kafka.receiver.max-commit-attempts=3", "spring.reactor.kafka.receiver.max-deferred-commits=5", - "spring.reactor.kafka.receiver.subscribe-topics=foo,bar", - "spring.reactor.kafka.receiver.subscribe-pattern=myTopic.+").run((context) -> { + "spring.reactor.kafka.receiver.subscribe-topics=foo,bar").run((context) -> { + ReceiverOptions receiverOptions = context.getBean(ReceiverOptions.class); + assertThat(receiverOptions.commitInterval()).isEqualTo(Duration.ofSeconds(2)); + assertThat(receiverOptions.closeTimeout()).isEqualTo(Duration.ofMillis(1500)); + assertThat(receiverOptions.commitBatchSize()).isEqualTo(100); + assertThat(receiverOptions.pollTimeout()).isEqualTo(Duration.ofSeconds(1)); + assertThat(receiverOptions.atmostOnceCommitAheadSize()).isEqualTo(42); + assertThat(receiverOptions.maxCommitAttempts()).isEqualTo(3); + assertThat(receiverOptions.maxDeferredCommits()).isEqualTo(5); + assertThat(receiverOptions.subscriptionTopics()).containsAll(Arrays.asList("foo", "bar")); + }); + } + + @Test + void receiverPropertiesSubscribePattern() { + this.contextRunner.withPropertyValues("spring.reactor.kafka.receiver.subscribe-pattern=myTopic.+") + .run((context) -> { ReceiverOptions receiverOptions = context.getBean(ReceiverOptions.class); - Map configs = receiverOptions.consumerProperties(); - assertThat(configs.get("commitInterval")).isEqualTo(2000); - assertThat(configs.get("closeTimeout")).isEqualTo(1500); - assertThat(configs.get("commitBatchSize")).isEqualTo(100); - assertThat(configs.get("pollTimeout")).isEqualTo(1000); - assertThat(configs.get("atmostOnceCommitAheadSize")).isEqualTo(42); - assertThat(configs.get("maxCommitAttempts")).isEqualTo(3); - assertThat(configs.get("maxDeferredCommits")).isEqualTo(5); - assertThat(configs.get("subscribeTopics")).isEqualTo(Arrays.asList("foo", "bar")); - assertThat((Pattern) configs.get("subscribePattern")) + assertThat(receiverOptions.subscriptionPattern()) .matches((p) -> Objects.equals(Pattern.compile("myTopic.+").pattern(), p.pattern())); }); } @Test - void producerProperties() { - this.contextRunner.withPropertyValues("spring.reactor.kafka.sender.max-in-flight=1500", - "spring.reactor.kafka.sender.stop-on-error=false", "spring.reactor.kafka.sender.close-timeout=500") + void receiverPropertiesDefaultValues() { + this.contextRunner.withPropertyValues() .run((context) -> { - SenderOptions senderOptions = context.getBean(SenderOptions.class); - Map configs = senderOptions.producerProperties(); - assertThat(configs.get("maxInFlight")).isEqualTo(1500); - assertThat((Boolean) configs.get("stopOnError")).isFalse(); - assertThat(configs.get("closeTimeout")).isEqualTo(500); + ReceiverOptions receiverOptions = context.getBean(ReceiverOptions.class); + assertThat(receiverOptions.commitInterval()).isEqualTo(Duration.ofSeconds(5)); }); } + @Test + void producerProperties() { + this.contextRunner.withPropertyValues( + "spring.reactor.kafka.sender.max-in-flight=1500", "spring.reactor.kafka.sender.stop-on-error=false", + "spring.reactor.kafka.sender.close-timeout=500") + .run((context) -> { + SenderOptions senderOptions = context + .getBean(SenderOptions.class); + assertThat(senderOptions.maxInFlight()).isEqualTo(1500); + assertThat(senderOptions.stopOnError()).isFalse(); + assertThat(senderOptions.closeTimeout()).isEqualTo(Duration.ofMillis(500)); + }); + } } From ce390b00e1e314d07caff984db054741c71ce29c Mon Sep 17 00:00:00 2001 From: Almog Tavor Date: Wed, 20 Apr 2022 17:49:37 +0300 Subject: [PATCH 08/12] Merge branch 'spring-projects:main' into main --- .../DocumentDevtoolsPropertyDefaults.java | 2 +- ci/images/ci-image-jdk18/Dockerfile | 2 +- ci/images/ci-image/Dockerfile | 2 +- gradle.properties | 2 +- settings.gradle | 2 +- .../build.gradle | 6 +- .../ReactiveCloudFoundrySecurityService.java | 5 +- ...estHealthContributorAutoConfiguration.java | 16 +- .../metrics/JvmMetricsAutoConfiguration.java | 10 +- .../KafkaMetricsAutoConfiguration.java | 4 +- .../Log4J2MetricsAutoConfiguration.java | 2 +- .../LogbackMetricsAutoConfiguration.java | 2 +- .../SystemMetricsAutoConfiguration.java | 6 +- .../CacheMetricsRegistrarConfiguration.java | 4 +- .../export/dynatrace/DynatraceProperties.java | 14 + .../DynatracePropertiesConfigAdapter.java | 5 + .../properties/PropertiesConfigAdapter.java | 4 +- ...vefrontMetricsExportAutoConfiguration.java | 38 +-- .../export/wavefront/WavefrontProperties.java | 132 -------- .../WavefrontPropertiesConfigAdapter.java | 34 +- ...ataSourcePoolMetricsAutoConfiguration.java | 115 ++++--- .../mongo/MongoMetricsAutoConfiguration.java | 12 +- .../TaskExecutorMetricsAutoConfiguration.java | 2 +- .../jetty/JettyMetricsAutoConfiguration.java | 6 +- .../TomcatMetricsAutoConfiguration.java | 2 +- .../ObservationAutoConfiguration.java | 4 +- .../ObservationRegistryConfigurer.java | 10 +- .../ObservationRegistryPostProcessor.java | 6 +- .../tracing/BraveAutoConfiguration.java | 129 ++++++++ .../MicrometerTracingAutoConfiguration.java | 46 +++ .../OpenTelemetryAutoConfiguration.java | 39 +++ .../tracing/OpenTelemetryConfigurations.java | 151 +++++++++ .../tracing/TracingProperties.java | 56 ++++ .../autoconfigure/tracing/package-info.java | 20 ++ .../wavefront/MeterRegistrySpanMetrics.java | 73 +++++ .../WavefrontTracingAutoConfiguration.java | 136 ++++++++ .../tracing/wavefront/package-info.java | 20 ++ .../zipkin/ZipkinAutoConfiguration.java | 57 ++++ .../tracing/zipkin/ZipkinConfigurations.java | 109 +++++++ .../tracing/zipkin/ZipkinProperties.java | 71 +++++ .../zipkin/ZipkinRestTemplateSender.java | 170 ++++++++++ .../tracing/zipkin/package-info.java | 20 ++ .../wavefront/WavefrontAutoConfiguration.java | 61 ++++ .../wavefront/WavefrontProperties.java | 290 ++++++++++++++++++ .../autoconfigure/wavefront/package-info.java | 20 ++ .../web/server/LocalManagementPort.java | 6 +- ...itional-spring-configuration-metadata.json | 20 +- ...ot.autoconfigure.AutoConfiguration.imports | 6 + .../SpringApplicationHierarchyTests.java | 22 +- ...althContributorAutoConfigurationTests.java | 110 +++++++ ...althContributorAutoConfigurationTests.java | 6 +- ...ngsEndpointReactiveDocumentationTests.java | 4 +- ...ingsEndpointServletDocumentationTests.java | 4 +- .../MetricsEndpointDocumentationTests.java | 2 +- ...theusScrapeEndpointDocumentationTests.java | 2 +- ...intsAutoConfigurationIntegrationTests.java | 8 +- .../JvmMetricsAutoConfigurationTests.java | 10 +- ...4jLoggerContextAutoConfigurationTests.java | 2 +- ...4jLoggerContextAutoConfigurationTests.java | 2 +- .../LogbackMetricsAutoConfigurationTests.java | 2 +- ...onfigurationWithLog4j2AndLogbackTests.java | 2 +- .../SystemMetricsAutoConfigurationTests.java | 6 +- .../CacheMetricsAutoConfigurationTests.java | 14 +- ...DynatracePropertiesConfigAdapterTests.java | 10 +- ...ioMetricsExportAutoConfigurationTests.java | 2 +- ...hRegistryPropertiesConfigAdapterTests.java | 4 +- ...ntMetricsExportAutoConfigurationTests.java | 69 +---- ...WavefrontPropertiesConfigAdapterTests.java | 49 ++- ...urcePoolMetricsAutoConfigurationTests.java | 31 +- .../MongoMetricsAutoConfigurationTests.java | 12 +- .../metrics/test/MetricsIntegrationTests.java | 4 +- .../TomcatMetricsAutoConfigurationTests.java | 2 +- .../ObservationAutoConfigurationTests.java | 16 +- ...mentWebSecurityAutoConfigurationTests.java | 8 +- .../tracing/BraveAutoConfigurationTests.java | 156 ++++++++++ ...crometerTracingAutoConfigurationTests.java | 88 ++++++ ...gurationsMicrometerConfigurationTests.java | 111 +++++++ ...ryConfigurationsSdkConfigurationTests.java | 112 +++++++ ...onfigurationsTracerConfigurationTests.java | 90 ++++++ .../MeterRegistrySpanMetricsTests.java | 101 ++++++ ...avefrontTracingAutoConfigurationTests.java | 192 ++++++++++++ .../tracing/zipkin/NoopSender.java | 62 ++++ .../zipkin/ZipkinAutoConfigurationTests.java | 71 +++++ ...ConfigurationsBraveConfigurationTests.java | 92 ++++++ ...ationsOpenTelemetryConfigurationTests.java | 104 +++++++ ...figurationsReporterConfigurationTests.java | 97 ++++++ ...onfigurationsSenderConfigurationTests.java | 100 ++++++ .../zipkin/ZipkinRestTemplateSenderTests.java | 122 ++++++++ .../WavefrontAutoConfigurationTests.java | 101 ++++++ ...avefrontPropertiesMetricsExportTests.java} | 20 +- .../wavefront/WavefrontPropertiesTests.java | 54 ++++ .../spring-boot-actuator/build.gradle | 1 - .../ElasticsearchReactiveHealthIndicator.java | 12 +- ...lasticsearchRestClientHealthIndicator.java | 85 +++++ .../ElasticsearchRestHealthIndicator.java | 56 +--- .../CaffeineCacheMeterBinderProvider.java | 2 +- .../HazelcastCacheMeterBinderProvider.java | 2 +- .../cache/JCacheCacheMeterBinderProvider.java | 2 +- .../startup/StartupTimeMetricsListener.java | 4 +- .../system/DiskSpaceMetricsBinder.java | 2 +- .../web/client/RestTemplateExchangeTags.java | 12 +- .../jetty/JettyConnectionMetricsBinder.java | 2 +- .../JettyServerThreadPoolMetricsBinder.java | 2 +- .../jetty/JettySslHandshakeMetricsBinder.java | 2 +- .../client/WebClientExchangeTags.java | 14 +- .../web/reactive/server/WebFluxTags.java | 20 +- .../web/tomcat/TomcatMetricsBinder.java | 2 +- ...ticsearchReactiveHealthIndicatorTests.java | 13 +- ...searchRestClientHealthIndicatorTests.java} | 16 +- .../MetricsEndpointWebIntegrationTests.java | 2 +- ...CaffeineCacheMeterBinderProviderTests.java | 2 +- ...azelcastCacheMeterBinderProviderTests.java | 2 +- .../JCacheCacheMeterBinderProviderTests.java | 2 +- .../StartupTimeMetricsListenerTests.java | 2 +- .../client/RestTemplateExchangeTagsTests.java | 19 +- ...ultWebClientExchangeTagsProviderTests.java | 14 +- .../MetricsWebClientFilterFunctionTests.java | 10 +- .../client/WebClientExchangeTagsTests.java | 23 +- .../web/reactive/server/WebFluxTagsTests.java | 4 +- .../spring-boot-autoconfigure/build.gradle | 1 + .../NoSuchBeanDefinitionFailureAnalyzer.java | 15 +- ...sticsearchRestClientAutoConfiguration.java | 3 + ...ElasticsearchRestClientConfigurations.java | 34 +- .../flyway/FlywayAutoConfiguration.java | 9 - .../saml2/Saml2RelyingPartyProperties.java | 10 +- ...RelyingPartyRegistrationConfiguration.java | 25 +- .../session/RedisSessionConfiguration.java | 6 +- .../AbstractErrorWebExceptionHandler.java | 2 +- ...itional-spring-configuration-metadata.json | 96 +++++- ...uchBeanDefinitionFailureAnalyzerTests.java | 15 +- ...ientAutoConfigurationIntegrationTests.java | 28 +- ...earchRestClientAutoConfigurationTests.java | 137 ++++++--- .../gson/GsonAutoConfigurationTests.java | 5 +- ...2ResourceServerAutoConfigurationTests.java | 15 +- ...ml2RelyingPartyAutoConfigurationTests.java | 38 +-- .../Saml2RelyingPartyPropertiesTests.java | 34 +- ...ymeleafReactiveAutoConfigurationTests.java | 3 +- .../WebClientAutoConfigurationTests.java | 29 -- .../servlet/WelcomePageIntegrationTests.java | 2 +- .../RemappedErrorViewIntegrationTests.java | 4 +- ...SocketMessagingAutoConfigurationTests.java | 10 +- .../spring-boot-dependencies/build.gradle | 80 +++-- ...DevToolsPropertyDefaultsPostProcessor.java | 3 +- .../client/ClassPathChangeUploader.java | 5 +- .../boot/devtools/restart/Restarter.java | 13 +- .../spring-boot-docs/build.gradle | 1 - .../src/docs/asciidoc/actuator/metrics.adoc | 8 +- .../container-images/dockerfiles.adoc | 4 +- .../src/docs/asciidoc/data/nosql.adoc | 19 +- .../asciidoc/features/spring-application.adoc | 3 + .../src/docs/asciidoc/howto/webserver.adoc | 27 +- .../src/docs/asciidoc/messaging/kafka.adoc | 2 +- .../docs/asciidoc/web/spring-security.adoc | 4 +- .../command/CustomCommandTagsProvider.java | 2 +- .../MyCommandTagsProviderConfiguration.java | 2 +- .../CustomConnectionPoolTagsProvider.java | 2 +- ...nnectionPoolTagsProviderConfiguration.java | 2 +- .../MyDataElasticsearchTests.java | 2 +- .../MyUserDocumentationTests.java | 2 +- .../discoverport/MyWebIntegrationTests.java | 4 +- .../command/CustomCommandTagsProvider.kt | 2 +- .../MyCommandTagsProviderConfiguration.kt | 2 +- .../CustomConnectionPoolTagsProvider.kt | 2 +- ...ConnectionPoolTagsProviderConfiguration.kt | 2 +- .../MyUserDocumentationTests.kt | 4 +- .../discoverport/MyWebIntegrationTests.kt | 2 +- .../spring-boot-starter-actuator/build.gradle | 1 - .../build.gradle | 1 - ...AdvancedConfigurationIntegrationTests.java | 2 +- ...DocsAutoConfigurationIntegrationTests.java | 2 +- .../test/context/SpringBootContextLoader.java | 44 ++- .../boot/test/context/SpringBootTest.java | 4 +- .../SpringBootTestContextBootstrapper.java | 8 +- .../server/LocalRSocketServerPort.java | 42 +++ .../test/rsocket/server/package-info.java | 20 ++ .../test/web/server/LocalManagementPort.java | 41 +++ .../boot/test/web/server/LocalServerPort.java | 42 +++ .../boot/test/web/server/package-info.java | 20 ++ ...stEmbeddedReactiveWebEnvironmentTests.java | 4 +- ...gBootTestWebServerWebEnvironmentTests.java | 2 +- .../context/SpringBootContextLoaderTests.java | 26 ++ .../server/LocalRSocketServerPortTests.java | 55 ++++ .../web/server/LocalManagementPortTests.java | 54 ++++ .../test/web/server/LocalServerPortTests.java | 55 ++++ .../buildpack/platform/build/ApiVersions.java | 14 +- .../platform/build/ApiVersionsTests.java | 8 + .../platform/build/LifecycleTests.java | 9 +- .../MetadataGenerationEnvironment.java | 4 - .../src/docs/asciidoc/running.adoc | 2 +- .../gradle/tasks/buildinfo/BuildInfo.java | 4 +- .../tasks/buildinfo/BuildInfoTests.java | 11 +- .../gradle/testkit/GradleBuild.java | 2 +- .../boot/ExitCodeGenerators.java | 20 +- .../boot/SpringApplication.java | 9 +- .../context/annotation/Configurations.java | 7 +- .../ConfigurationPropertiesBean.java | 12 +- .../boot/diagnostics/FailureAnalyzers.java | 4 +- ...eanCurrentlyInCreationFailureAnalyzer.java | 18 +- ...igurationPropertyValueFailureAnalyzer.java | 11 +- ...onfigurationPropertiesFailureAnalyzer.java | 13 +- ...NoUniqueBeanDefinitionFailureAnalyzer.java | 13 +- .../boot/jdbc/DatabaseDriver.java | 5 - .../context/LocalRSocketServerPort.java | 5 +- .../netty/NettyRSocketServerFactory.java | 16 +- .../MissingWebServerFactoryBeanException.java | 59 ++++ ...ngWebServerFactoryBeanFailureAnalyzer.java | 47 +++ .../jetty/JettyReactiveWebServerFactory.java | 4 +- .../jetty/JettyServletWebServerFactory.java | 2 +- .../netty/NettyReactiveWebServerFactory.java | 5 +- .../TomcatReactiveWebServerFactory.java | 2 +- .../tomcat/TomcatServletWebServerFactory.java | 2 +- .../UndertowWebServerFactoryDelegate.java | 5 +- .../ReactiveWebServerApplicationContext.java | 8 +- .../error/DefaultErrorAttributes.java | 7 +- .../server/ReactiveWebServerFactory.java | 5 +- .../AbstractConfigurableWebServerFactory.java | 15 +- .../CertificateFileSslStoreProvider.java | 118 +++++++ .../boot/web/server/CertificateParser.java | 109 +++++++ .../boot/web/server/LocalServerPort.java | 5 +- .../boot/web/server/PrivateKeyParser.java | 149 +++++++++ .../springframework/boot/web/server/Ssl.java | 59 +++- .../ServletWebServerApplicationContext.java | 6 +- .../server/ServletWebServerFactory.java | 5 +- .../main/resources/META-INF/spring.factories | 1 + .../boot/ExitCodeGeneratorsTests.java | 35 ++- .../boot/SpringBootVersionTests.java | 2 +- .../ConfigurationPropertiesBeanTests.java | 21 ++ ...rrentlyInCreationFailureAnalyzerTests.java | 21 +- ...tionPropertyValueFailureAnalyzerTests.java | 9 +- ...urationPropertiesFailureAnalyzerTests.java | 9 +- ...queBeanDefinitionFailureAnalyzerTests.java | 27 +- .../context/LocalRSocketServerPortTests.java | 3 +- .../netty/NettyRSocketServerFactoryTests.java | 42 +++ ...ServerFactoryBeanFailureAnalyzerTests.java | 75 +++++ .../TomcatServletWebServerFactoryTests.java | 13 +- ...ctiveWebServerApplicationContextTests.java | 2 +- ...AbstractReactiveWebServerFactoryTests.java | 23 +- .../CertificateFileSslStoreProviderTests.java | 133 ++++++++ .../web/server/CertificateParserTests.java | 57 ++++ .../boot/web/server/LocalServerPortTests.java | 3 +- .../web/server/PrivateKeyParserTests.java | 53 ++++ .../AbstractServletWebServerFactoryTests.java | 28 ++ .../src/test/resources/test-cert-chain.pem | 32 ++ .../src/test/resources/test-cert.pem | 17 + .../src/test/resources/test-key.pem | 28 ++ .../CustomServletPathSampleActuatorTests.java | 4 +- ...AndPathSampleActuatorApplicationTests.java | 6 +- ...tCustomServletPathSampleActuatorTests.java | 6 +- ...ctuatorCustomSecurityApplicationTests.java | 4 +- .../SampleActuatorUiApplicationPortTests.java | 6 +- ...AndPathSampleActuatorApplicationTests.java | 6 +- ...gementAddressActuatorApplicationTests.java | 6 +- ...entPortSampleActuatorApplicationTests.java | 4 +- ...entPortSampleActuatorApplicationTests.java | 6 +- ...gementPortWithLazyInitializationTests.java | 4 +- .../SampleOAuth2ClientApplicationTests.java | 4 +- .../profile/ActiveProfilesTests.java | 3 +- .../SampleRSocketApplicationTests.java | 4 +- .../src/main/resources/application.yml | 8 +- ...mpleSaml2RelyingPartyApplicationTests.java | 6 +- ...anagementPortSampleSecureWebFluxTests.java | 6 +- .../SampleSessionRedisApplicationTests.java | 2 + .../SampleSessionWebFluxApplicationTests.java | 2 +- ...leTomcatTwoConnectorsApplicationTests.java | 4 +- .../build.gradle | 13 + .../SampleWebApplicationTypeApplication.java | 29 ++ .../src/main/resources/application.properties | 1 + ...denWebApplicationTypeApplicationTests.java | 44 +++ ...pleWebApplicationTypeApplicationTests.java | 44 +++ ...tNoneOverridesWebApplicationTypeTests.java | 48 +++ .../SampleGroovyTemplateApplicationTests.java | 4 +- .../SampleMethodSecurityApplicationTests.java | 4 +- ...SampleWebSecureCustomApplicationTests.java | 4 +- .../SampleWebSecureJdbcApplicationTests.java | 4 +- .../SampleWebSecureApplicationTests.java | 4 +- .../SampleWebUiApplicationTests.java | 2 +- ...entPortSampleActuatorApplicationTests.java | 4 +- .../webservices/SampleWsApplicationTests.java | 4 +- .../SampleWebSocketsApplicationTests.java | 4 +- ...omContainerWebSocketsApplicationTests.java | 4 +- .../SampleWebSocketsApplicationTests.java | 4 +- ...omContainerWebSocketsApplicationTests.java | 4 +- .../SampleWebSocketsApplicationTests.java | 4 +- ...omContainerWebSocketsApplicationTests.java | 4 +- src/checkstyle/import-control.xml | 3 + 285 files changed, 6151 insertions(+), 1106 deletions(-) delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontProperties.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfiguration.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfiguration.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurations.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/TracingProperties.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/package-info.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/MeterRegistrySpanMetrics.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfiguration.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/package-info.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfiguration.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinProperties.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSender.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/package-info.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfiguration.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontProperties.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/package-info.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsMicrometerConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsSdkConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsTracerConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/MeterRegistrySpanMetricsTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/NoopSender.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsBraveConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsReporterConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsSenderConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSenderTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfigurationTests.java rename spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/{metrics/export/wavefront/WavefrontPropertiesTests.java => wavefront/WavefrontPropertiesMetricsExportTests.java} (58%) create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontPropertiesTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicator.java rename spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/{ElasticsearchRestHealthIndicatorTests.java => ElasticsearchRestClientHealthIndicatorTests.java} (90%) create mode 100644 spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/rsocket/server/LocalRSocketServerPort.java create mode 100644 spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/rsocket/server/package-info.java create mode 100644 spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalManagementPort.java create mode 100644 spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalServerPort.java create mode 100644 spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/package-info.java create mode 100644 spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/rsocket/server/LocalRSocketServerPortTests.java create mode 100644 spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalManagementPortTests.java create mode 100644 spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalServerPortTests.java create mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanException.java create mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzer.java create mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/CertificateFileSslStoreProvider.java create mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/CertificateParser.java create mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PrivateKeyParser.java create mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzerTests.java create mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CertificateFileSslStoreProviderTests.java create mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CertificateParserTests.java create mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/PrivateKeyParserTests.java create mode 100644 spring-boot-project/spring-boot/src/test/resources/test-cert-chain.pem create mode 100644 spring-boot-project/spring-boot/src/test/resources/test-cert.pem create mode 100644 spring-boot-project/spring-boot/src/test/resources/test-key.pem create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/build.gradle create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/main/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplication.java create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/main/resources/application.properties create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/OverriddenWebApplicationTypeApplicationTests.java create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplicationTests.java create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/WebEnvironmentNoneOverridesWebApplicationTypeTests.java diff --git a/buildSrc/src/main/java/org/springframework/boot/build/devtools/DocumentDevtoolsPropertyDefaults.java b/buildSrc/src/main/java/org/springframework/boot/build/devtools/DocumentDevtoolsPropertyDefaults.java index bb9ac2d52576..ef86b4a7ffd4 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/devtools/DocumentDevtoolsPropertyDefaults.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/devtools/DocumentDevtoolsPropertyDefaults.java @@ -41,7 +41,7 @@ */ public class DocumentDevtoolsPropertyDefaults extends DefaultTask { - private Configuration devtools; + private final Configuration devtools; private final RegularFileProperty outputFile; diff --git a/ci/images/ci-image-jdk18/Dockerfile b/ci/images/ci-image-jdk18/Dockerfile index 08258db4cdca..8dda41f84a65 100644 --- a/ci/images/ci-image-jdk18/Dockerfile +++ b/ci/images/ci-image-jdk18/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:focal-20220316 +FROM ubuntu:focal-20220404 ADD setup.sh /setup.sh ADD get-jdk-url.sh /get-jdk-url.sh diff --git a/ci/images/ci-image/Dockerfile b/ci/images/ci-image/Dockerfile index 254602311f76..68fd44c7b44d 100644 --- a/ci/images/ci-image/Dockerfile +++ b/ci/images/ci-image/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:focal-20220316 +FROM ubuntu:focal-20220404 ADD setup.sh /setup.sh ADD get-jdk-url.sh /get-jdk-url.sh diff --git a/gradle.properties b/gradle.properties index cf0f92064c7c..d3416ca15f3d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ org.gradle.caching=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8 -kotlinVersion=1.6.20-RC2 +kotlinVersion=1.6.20 tomcatVersion=10.0.18 kotlin.stdlib.default.dependency=false diff --git a/settings.gradle b/settings.gradle index b2a608a6351f..d824aa229fb1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -22,7 +22,7 @@ pluginManagement { } plugins { - id "com.gradle.enterprise" version "3.8.1" + id "com.gradle.enterprise" version "3.9" id "io.spring.ge.conventions" version "0.0.9" } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle b/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle index 04d9da39e855..f8e30f8a1afc 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle @@ -50,7 +50,9 @@ dependencies { optional("io.micrometer:micrometer-observation") optional("io.micrometer:micrometer-core") optional("io.micrometer:micrometer-tracing-api") - optional("io.micrometer:micrometer-binders") + optional("io.micrometer:micrometer-tracing-bridge-brave") + optional("io.micrometer:micrometer-tracing-bridge-otel") + optional("io.micrometer:micrometer-tracing-reporter-wavefront") optional("io.micrometer:micrometer-registry-appoptics") optional("io.micrometer:micrometer-registry-atlas") { exclude group: "javax.inject", module: "javax.inject" @@ -76,6 +78,8 @@ dependencies { optional("io.micrometer:micrometer-registry-signalfx") optional("io.micrometer:micrometer-registry-statsd") optional("io.micrometer:micrometer-registry-wavefront") + optional("io.zipkin.reporter2:zipkin-sender-urlconnection") + optional("io.opentelemetry:opentelemetry-exporter-zipkin") optional("io.projectreactor.netty:reactor-netty-http") optional("io.r2dbc:r2dbc-pool") optional("io.r2dbc:r2dbc-spi") diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityService.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityService.java index 7f9a83b3f15e..55d2cfd562da 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityService.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityService.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -31,6 +31,7 @@ import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.util.Assert; import org.springframework.web.reactive.function.client.WebClient; @@ -90,7 +91,7 @@ Mono getAccessLevel(String token, String applicationId) throws Clou private Throwable mapError(Throwable throwable) { if (throwable instanceof WebClientResponseException) { - HttpStatus statusCode = ((WebClientResponseException) throwable).getStatusCode(); + HttpStatusCode statusCode = ((WebClientResponseException) throwable).getStatusCode(); if (statusCode.equals(HttpStatus.FORBIDDEN)) { return new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied"); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfiguration.java index 51e2b1e83f57..adc2194cd7ff 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfiguration.java @@ -22,7 +22,7 @@ import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration; import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestHealthIndicator; +import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestClientHealthIndicator; import org.springframework.boot.actuate.health.HealthContributor; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -34,23 +34,21 @@ /** * {@link EnableAutoConfiguration Auto-configuration} for - * {@link ElasticsearchRestHealthIndicator} using the {@link RestClient}. + * {@link ElasticsearchRestClientHealthIndicator}. * * @author Artsiom Yudovin * @since 2.1.1 */ -@SuppressWarnings("deprecation") @AutoConfiguration(after = ElasticsearchRestClientAutoConfiguration.class) -@ConditionalOnClass(org.elasticsearch.client.RestHighLevelClient.class) -@ConditionalOnBean(org.elasticsearch.client.RestHighLevelClient.class) +@ConditionalOnClass(RestClient.class) +@ConditionalOnBean(RestClient.class) @ConditionalOnEnabledHealthIndicator("elasticsearch") -public class ElasticSearchRestHealthContributorAutoConfiguration extends - CompositeHealthContributorConfiguration { +public class ElasticSearchRestHealthContributorAutoConfiguration + extends CompositeHealthContributorConfiguration { @Bean @ConditionalOnMissingBean(name = { "elasticsearchHealthIndicator", "elasticsearchHealthContributor" }) - public HealthContributor elasticsearchHealthContributor( - Map clients) { + public HealthContributor elasticsearchHealthContributor(Map clients) { return createContributor(clients); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfiguration.java index 4dca3308441f..929b7024bf97 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfiguration.java @@ -16,12 +16,12 @@ package org.springframework.boot.actuate.autoconfigure.metrics; -import io.micrometer.binder.jvm.ClassLoaderMetrics; -import io.micrometer.binder.jvm.JvmGcMetrics; -import io.micrometer.binder.jvm.JvmHeapPressureMetrics; -import io.micrometer.binder.jvm.JvmMemoryMetrics; -import io.micrometer.binder.jvm.JvmThreadMetrics; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics; +import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics; +import io.micrometer.core.instrument.binder.jvm.JvmHeapPressureMetrics; +import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; +import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/KafkaMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/KafkaMetricsAutoConfiguration.java index 31842b7e5826..fc5c39ca7771 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/KafkaMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/KafkaMetricsAutoConfiguration.java @@ -16,9 +16,9 @@ package org.springframework.boot.actuate.autoconfigure.metrics; -import io.micrometer.binder.kafka.KafkaClientMetrics; -import io.micrometer.binder.kafka.KafkaStreamsMetrics; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.kafka.KafkaClientMetrics; +import io.micrometer.core.instrument.binder.kafka.KafkaStreamsMetrics; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfiguration.java index f9a76f607206..d2039e0466f9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfiguration.java @@ -16,8 +16,8 @@ package org.springframework.boot.actuate.autoconfigure.metrics; -import io.micrometer.binder.logging.Log4j2Metrics; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.logging.Log4j2Metrics; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.spi.LoggerContext; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfiguration.java index 1d1c19540b75..8a76340ff22a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfiguration.java @@ -17,8 +17,8 @@ package org.springframework.boot.actuate.autoconfigure.metrics; import ch.qos.logback.classic.LoggerContext; -import io.micrometer.binder.logging.LogbackMetrics; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.logging.LogbackMetrics; import org.slf4j.ILoggerFactory; import org.slf4j.LoggerFactory; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfiguration.java index f113d7144384..30111b97e800 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfiguration.java @@ -19,11 +19,11 @@ import java.io.File; import java.util.List; -import io.micrometer.binder.system.FileDescriptorMetrics; -import io.micrometer.binder.system.ProcessorMetrics; -import io.micrometer.binder.system.UptimeMetrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tags; +import io.micrometer.core.instrument.binder.system.FileDescriptorMetrics; +import io.micrometer.core.instrument.binder.system.ProcessorMetrics; +import io.micrometer.core.instrument.binder.system.UptimeMetrics; import org.springframework.boot.actuate.metrics.system.DiskSpaceMetricsBinder; import org.springframework.boot.autoconfigure.AutoConfiguration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsRegistrarConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsRegistrarConfiguration.java index d1b402ec36fb..9c074c77da9b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsRegistrarConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsRegistrarConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-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. @@ -72,7 +72,7 @@ private void bindCacheManagerToRegistry(String beanName, CacheManager cacheManag } private void bindCacheToRegistry(String beanName, Cache cache) { - Tag cacheManagerTag = Tag.of("cacheManager", getCacheManagerName(beanName)); + Tag cacheManagerTag = Tag.of("cache.manager", getCacheManagerName(beanName)); this.cacheMetricsRegistrar.bindCacheToRegistry(cache, cacheManagerTag); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceProperties.java index 10a837b8895e..c1bd8ea930db 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceProperties.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceProperties.java @@ -168,6 +168,12 @@ public static class V2 { */ private String metricKeyPrefix; + /** + * Whether to fall back to the built-in micrometer instruments for Timer and + * DistributionSummary. + */ + private boolean useDynatraceSummaryInstruments = true; + public Map getDefaultDimensions() { return this.defaultDimensions; } @@ -192,6 +198,14 @@ public void setMetricKeyPrefix(String metricKeyPrefix) { this.metricKeyPrefix = metricKeyPrefix; } + public boolean isUseDynatraceSummaryInstruments() { + return this.useDynatraceSummaryInstruments; + } + + public void setUseDynatraceSummaryInstruments(boolean useDynatraceSummaryInstruments) { + this.useDynatraceSummaryInstruments = useDynatraceSummaryInstruments; + } + } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapter.java index 6bcb21b9de93..82135f989860 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapter.java @@ -90,6 +90,11 @@ public boolean enrichWithDynatraceMetadata() { return get(v2(V2::isEnrichWithDynatraceMetadata), DynatraceConfig.super::enrichWithDynatraceMetadata); } + @Override + public boolean useDynatraceSummaryInstruments() { + return get(v2(V2::isUseDynatraceSummaryInstruments), DynatraceConfig.super::useDynatraceSummaryInstruments); + } + private Function v1(Function getter) { return (properties) -> getter.apply(properties.getV1()); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PropertiesConfigAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PropertiesConfigAdapter.java index 13e8a7af7bcc..4cc34a988868 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PropertiesConfigAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -31,7 +31,7 @@ */ public class PropertiesConfigAdapter { - private T properties; + private final T properties; /** * Create a new {@link PropertiesConfigAdapter} instance. diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfiguration.java index 9524db72cfdf..386bec08d282 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfiguration.java @@ -16,10 +16,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront; -import java.time.Duration; - import com.wavefront.sdk.common.WavefrontSender; -import com.wavefront.sdk.common.clients.WavefrontClient.Builder; import io.micrometer.core.instrument.Clock; import io.micrometer.wavefront.WavefrontConfig; import io.micrometer.wavefront.WavefrontMeterRegistry; @@ -28,16 +25,15 @@ import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront.WavefrontProperties.Sender; +import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.context.annotation.Bean; -import org.springframework.util.unit.DataSize; /** * {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to Wavefront. @@ -49,29 +45,17 @@ */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, - after = MetricsAutoConfiguration.class) -@ConditionalOnBean(Clock.class) + after = { MetricsAutoConfiguration.class, WavefrontAutoConfiguration.class }) +@ConditionalOnBean({ Clock.class, WavefrontSender.class }) @ConditionalOnClass({ WavefrontMeterRegistry.class, WavefrontSender.class }) @ConditionalOnEnabledMetricsExport("wavefront") @EnableConfigurationProperties(WavefrontProperties.class) public class WavefrontMetricsExportAutoConfiguration { - private final WavefrontProperties properties; - - public WavefrontMetricsExportAutoConfiguration(WavefrontProperties properties) { - this.properties = properties; - } - - @Bean - @ConditionalOnMissingBean - public WavefrontConfig wavefrontConfig() { - return new WavefrontPropertiesConfigAdapter(this.properties); - } - @Bean @ConditionalOnMissingBean - public WavefrontSender wavefrontSender(WavefrontConfig wavefrontConfig) { - return createWavefrontSender(wavefrontConfig); + public WavefrontConfig wavefrontConfig(WavefrontProperties properties) { + return new WavefrontPropertiesConfigAdapter(properties); } @Bean @@ -81,14 +65,4 @@ public WavefrontMeterRegistry wavefrontMeterRegistry(WavefrontConfig wavefrontCo return WavefrontMeterRegistry.builder(wavefrontConfig).clock(clock).wavefrontSender(wavefrontSender).build(); } - private WavefrontSender createWavefrontSender(WavefrontConfig wavefrontConfig) { - Builder builder = WavefrontMeterRegistry.getDefaultSenderBuilder(wavefrontConfig); - PropertyMapper mapper = PropertyMapper.get().alwaysApplyingWhenNonNull(); - Sender sender = this.properties.getSender(); - mapper.from(sender.getMaxQueueSize()).to(builder::maxQueueSize); - mapper.from(sender.getFlushInterval()).asInt(Duration::getSeconds).to(builder::flushIntervalSeconds); - mapper.from(sender.getMessageSize()).asInt(DataSize::toBytes).to(builder::messageSizeBytes); - return builder.build(); - } - } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontProperties.java deleted file mode 100644 index 0d3949c6b864..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontProperties.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.metrics.export.wavefront; - -import java.net.URI; -import java.time.Duration; - -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PushRegistryProperties; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.util.unit.DataSize; - -/** - * {@link ConfigurationProperties @ConfigurationProperties} for configuring Wavefront - * metrics export. - * - * @author Jon Schneider - * @author Stephane Nicoll - * @since 2.0.0 - */ -@ConfigurationProperties("management.wavefront.metrics.export") -public class WavefrontProperties extends PushRegistryProperties { - - /** - * URI to ship metrics to. - */ - private URI uri = URI.create("https://longboard.wavefront.com"); - - /** - * Unique identifier for the app instance that is the source of metrics being - * published to Wavefront. Defaults to the local host name. - */ - private String source; - - /** - * API token used when publishing metrics directly to the Wavefront API host. - */ - private String apiToken; - - /** - * Global prefix to separate metrics originating from this app's white box - * instrumentation from those originating from other Wavefront integrations when - * viewed in the Wavefront UI. - */ - private String globalPrefix; - - private final Sender sender = new Sender(); - - public URI getUri() { - return this.uri; - } - - public void setUri(URI uri) { - this.uri = uri; - } - - public String getSource() { - return this.source; - } - - public void setSource(String source) { - this.source = source; - } - - public String getApiToken() { - return this.apiToken; - } - - public void setApiToken(String apiToken) { - this.apiToken = apiToken; - } - - public String getGlobalPrefix() { - return this.globalPrefix; - } - - public void setGlobalPrefix(String globalPrefix) { - this.globalPrefix = globalPrefix; - } - - public Sender getSender() { - return this.sender; - } - - public static class Sender { - - private int maxQueueSize = 50000; - - private Duration flushInterval = Duration.ofSeconds(1); - - private DataSize messageSize = DataSize.ofBytes(Integer.MAX_VALUE); - - public int getMaxQueueSize() { - return this.maxQueueSize; - } - - public void setMaxQueueSize(int maxQueueSize) { - this.maxQueueSize = maxQueueSize; - } - - public Duration getFlushInterval() { - return this.flushInterval; - } - - public void setFlushInterval(Duration flushInterval) { - this.flushInterval = flushInterval; - } - - public DataSize getMessageSize() { - return this.messageSize; - } - - public void setMessageSize(DataSize messageSize) { - this.messageSize = messageSize; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapter.java index a46e5c4ee5bc..8422593ff124 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapter.java @@ -19,18 +19,24 @@ import io.micrometer.wavefront.WavefrontConfig; import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PushRegistryPropertiesConfigAdapter; +import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties; +import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties.Metrics.Export; /** - * Adapter to convert {@link WavefrontProperties} to a {@link WavefrontConfig}. + * Adapter to convert {@link WavefrontProperties.Metrics} to a {@link WavefrontConfig}. * * @author Jon Schneider + * @author Moritz Halbritter * @since 2.0.0 */ -public class WavefrontPropertiesConfigAdapter extends PushRegistryPropertiesConfigAdapter - implements WavefrontConfig { +public class WavefrontPropertiesConfigAdapter + extends PushRegistryPropertiesConfigAdapter implements WavefrontConfig { + + private final WavefrontProperties properties; public WavefrontPropertiesConfigAdapter(WavefrontProperties properties) { - super(properties); + super(properties.getMetrics().getExport()); + this.properties = properties; } @Override @@ -39,32 +45,28 @@ public String prefix() { } @Override - public String get(String k) { - return null; + public String uri() { + return this.properties.getEffectiveUri().toString(); } @Override - public String uri() { - return get(this::getUriAsString, WavefrontConfig.DEFAULT_DIRECT::uri); + public String source() { + return this.properties.getSourceOrDefault(); } @Override - public String source() { - return get(WavefrontProperties::getSource, WavefrontConfig.super::source); + public int batchSize() { + return this.properties.getSender().getBatchSize(); } @Override public String apiToken() { - return get(WavefrontProperties::getApiToken, WavefrontConfig.super::apiToken); + return this.properties.getApiTokenOrThrow(); } @Override public String globalPrefix() { - return get(WavefrontProperties::getGlobalPrefix, WavefrontConfig.super::globalPrefix); - } - - private String getUriAsString(WavefrontProperties properties) { - return (properties.getUri() != null) ? properties.getUri().toString() : null; + return get(Export::getGlobalPrefix, WavefrontConfig.super::globalPrefix); } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration.java index c78bea92e5e1..8816f91ce557 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration.java @@ -28,11 +28,11 @@ import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.metrics.micrometer.MicrometerMetricsTrackerFactory; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.MeterBinder; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.actuate.metrics.jdbc.DataSourcePoolMetrics; @@ -43,6 +43,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.jdbc.DataSourceUnwrapper; import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadataProvider; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.log.LogMessage; import org.springframework.util.StringUtils; @@ -66,33 +67,52 @@ static class DataSourcePoolMetadataMetricsConfiguration { private static final String DATASOURCE_SUFFIX = "dataSource"; - @Autowired - void bindDataSourcesToRegistry(Map dataSources, MeterRegistry registry, + @Bean + DataSourcePoolMetadataMeterBinder dataSourcePoolMetadataMeterBinder(Map dataSources, ObjectProvider metadataProviders) { - List metadataProvidersList = metadataProviders.stream() - .collect(Collectors.toList()); - dataSources.forEach( - (name, dataSource) -> bindDataSourceToRegistry(name, dataSource, metadataProvidersList, registry)); + return new DataSourcePoolMetadataMeterBinder(dataSources, metadataProviders); } - private void bindDataSourceToRegistry(String beanName, DataSource dataSource, - Collection metadataProviders, MeterRegistry registry) { - String dataSourceName = getDataSourceName(beanName); - new DataSourcePoolMetrics(dataSource, metadataProviders, dataSourceName, Collections.emptyList()) - .bindTo(registry); - } + static class DataSourcePoolMetadataMeterBinder implements MeterBinder { + + private final Map dataSources; + + private final ObjectProvider metadataProviders; + + DataSourcePoolMetadataMeterBinder(Map dataSources, + ObjectProvider metadataProviders) { + this.dataSources = dataSources; + this.metadataProviders = metadataProviders; + } - /** - * Get the name of a DataSource based on its {@code beanName}. - * @param beanName the name of the data source bean - * @return a name for the given data source - */ - private String getDataSourceName(String beanName) { - if (beanName.length() > DATASOURCE_SUFFIX.length() - && StringUtils.endsWithIgnoreCase(beanName, DATASOURCE_SUFFIX)) { - return beanName.substring(0, beanName.length() - DATASOURCE_SUFFIX.length()); + @Override + public void bindTo(MeterRegistry registry) { + List metadataProvidersList = this.metadataProviders.stream() + .collect(Collectors.toList()); + this.dataSources.forEach((name, dataSource) -> bindDataSourceToRegistry(name, dataSource, + metadataProvidersList, registry)); + } + + private void bindDataSourceToRegistry(String beanName, DataSource dataSource, + Collection metadataProviders, MeterRegistry registry) { + String dataSourceName = getDataSourceName(beanName); + new DataSourcePoolMetrics(dataSource, metadataProviders, dataSourceName, Collections.emptyList()) + .bindTo(registry); + } + + /** + * Get the name of a DataSource based on its {@code beanName}. + * @param beanName the name of the data source bean + * @return a name for the given data source + */ + private String getDataSourceName(String beanName) { + if (beanName.length() > DATASOURCE_SUFFIX.length() + && StringUtils.endsWithIgnoreCase(beanName, DATASOURCE_SUFFIX)) { + return beanName.substring(0, beanName.length() - DATASOURCE_SUFFIX.length()); + } + return beanName; } - return beanName; + } } @@ -101,34 +121,43 @@ private String getDataSourceName(String beanName) { @ConditionalOnClass(HikariDataSource.class) static class HikariDataSourceMetricsConfiguration { - private static final Log logger = LogFactory.getLog(HikariDataSourceMetricsConfiguration.class); + @Bean + HikariDataSourceMeterBinder hikariDataSourceMeterBinder(ObjectProvider dataSources) { + return new HikariDataSourceMeterBinder(dataSources); + } - private final MeterRegistry registry; + static class HikariDataSourceMeterBinder implements MeterBinder { - HikariDataSourceMetricsConfiguration(MeterRegistry registry) { - this.registry = registry; - } + private static final Log logger = LogFactory.getLog(HikariDataSourceMeterBinder.class); - @Autowired - void bindMetricsRegistryToHikariDataSources(Collection dataSources) { - for (DataSource dataSource : dataSources) { - HikariDataSource hikariDataSource = DataSourceUnwrapper.unwrap(dataSource, HikariConfigMXBean.class, - HikariDataSource.class); - if (hikariDataSource != null) { - bindMetricsRegistryToHikariDataSource(hikariDataSource); - } + private final ObjectProvider dataSources; + + HikariDataSourceMeterBinder(ObjectProvider dataSources) { + this.dataSources = dataSources; } - } - private void bindMetricsRegistryToHikariDataSource(HikariDataSource hikari) { - if (hikari.getMetricRegistry() == null && hikari.getMetricsTrackerFactory() == null) { - try { - hikari.setMetricsTrackerFactory(new MicrometerMetricsTrackerFactory(this.registry)); + @Override + public void bindTo(MeterRegistry registry) { + for (DataSource dataSource : this.dataSources) { + HikariDataSource hikariDataSource = DataSourceUnwrapper.unwrap(dataSource, HikariConfigMXBean.class, + HikariDataSource.class); + if (hikariDataSource != null) { + bindMetricsRegistryToHikariDataSource(hikariDataSource, registry); + } } - catch (Exception ex) { - logger.warn(LogMessage.format("Failed to bind Hikari metrics: %s", ex.getMessage())); + } + + private void bindMetricsRegistryToHikariDataSource(HikariDataSource hikari, MeterRegistry registry) { + if (hikari.getMetricRegistry() == null && hikari.getMetricsTrackerFactory() == null) { + try { + hikari.setMetricsTrackerFactory(new MicrometerMetricsTrackerFactory(registry)); + } + catch (Exception ex) { + logger.warn(LogMessage.format("Failed to bind Hikari metrics: %s", ex.getMessage())); + } } } + } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfiguration.java index 4c66f9dd92f5..1e448b46f0ed 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfiguration.java @@ -17,13 +17,13 @@ package org.springframework.boot.actuate.autoconfigure.metrics.mongo; import com.mongodb.MongoClientSettings; -import io.micrometer.binder.mongodb.DefaultMongoCommandTagsProvider; -import io.micrometer.binder.mongodb.DefaultMongoConnectionPoolTagsProvider; -import io.micrometer.binder.mongodb.MongoCommandTagsProvider; -import io.micrometer.binder.mongodb.MongoConnectionPoolTagsProvider; -import io.micrometer.binder.mongodb.MongoMetricsCommandListener; -import io.micrometer.binder.mongodb.MongoMetricsConnectionPoolListener; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.mongodb.DefaultMongoCommandTagsProvider; +import io.micrometer.core.instrument.binder.mongodb.DefaultMongoConnectionPoolTagsProvider; +import io.micrometer.core.instrument.binder.mongodb.MongoCommandTagsProvider; +import io.micrometer.core.instrument.binder.mongodb.MongoConnectionPoolTagsProvider; +import io.micrometer.core.instrument.binder.mongodb.MongoMetricsCommandListener; +import io.micrometer.core.instrument.binder.mongodb.MongoMetricsConnectionPoolListener; import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfiguration.java index be30193c2cc5..e530be89bc95 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfiguration.java @@ -21,8 +21,8 @@ import java.util.concurrent.Executor; import java.util.concurrent.ThreadPoolExecutor; -import io.micrometer.binder.jvm.ExecutorServiceMetrics; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.jvm.ExecutorServiceMetrics; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfiguration.java index 7b6cc708da8a..4bd6eb69bfcd 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfiguration.java @@ -16,10 +16,10 @@ package org.springframework.boot.actuate.autoconfigure.metrics.web.jetty; -import io.micrometer.binder.jetty.JettyConnectionMetrics; -import io.micrometer.binder.jetty.JettyServerThreadPoolMetrics; -import io.micrometer.binder.jetty.JettySslHandshakeMetrics; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.jetty.JettyConnectionMetrics; +import io.micrometer.core.instrument.binder.jetty.JettyServerThreadPoolMetrics; +import io.micrometer.core.instrument.binder.jetty.JettySslHandshakeMetrics; import org.eclipse.jetty.server.Server; import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfiguration.java index c81aeb62c4af..b5818258b87d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfiguration.java @@ -16,8 +16,8 @@ package org.springframework.boot.actuate.autoconfigure.metrics.web.tomcat; -import io.micrometer.binder.tomcat.TomcatMetrics; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.tomcat.TomcatMetrics; import org.apache.catalina.Manager; import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java index 1b0f9c420512..c0114bf211f1 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java @@ -17,7 +17,7 @@ package org.springframework.boot.actuate.autoconfigure.observation; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.observation.Observation.GlobalTagsProvider; +import io.micrometer.observation.Observation.GlobalKeyValuesProvider; import io.micrometer.observation.ObservationHandler; import io.micrometer.observation.ObservationPredicate; import io.micrometer.observation.ObservationRegistry; @@ -48,7 +48,7 @@ public class ObservationAutoConfiguration { static ObservationRegistryPostProcessor observationRegistryPostProcessor( ObjectProvider> observationRegistryCustomizers, ObjectProvider observationPredicates, - ObjectProvider> tagProviders, + ObjectProvider> tagProviders, ObjectProvider> observationHandlers, ObjectProvider observationHandlerGrouping) { return new ObservationRegistryPostProcessor(observationRegistryCustomizers, observationPredicates, tagProviders, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryConfigurer.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryConfigurer.java index e4f0c88d35f6..83cb91eb837a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryConfigurer.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryConfigurer.java @@ -18,7 +18,7 @@ import java.util.List; -import io.micrometer.observation.Observation.GlobalTagsProvider; +import io.micrometer.observation.Observation.GlobalKeyValuesProvider; import io.micrometer.observation.ObservationHandler; import io.micrometer.observation.ObservationPredicate; import io.micrometer.observation.ObservationRegistry; @@ -29,7 +29,7 @@ /** * Configurer to apply {@link ObservationRegistryCustomizer customizers} to * {@link ObservationRegistry observation registries}. Installs - * {@link ObservationPredicate observation predicates} and {@link GlobalTagsProvider + * {@link ObservationPredicate observation predicates} and {@link GlobalKeyValuesProvider * global tag providers} into the {@link ObservationRegistry}. Also uses a * {@link ObservationHandlerGrouping} to group handlers, which are then added to the * {@link ObservationRegistry}. @@ -42,7 +42,7 @@ class ObservationRegistryConfigurer { private final ObjectProvider observationPredicates; - private final ObjectProvider> tagProviders; + private final ObjectProvider> tagProviders; private final ObjectProvider> observationHandlers; @@ -50,7 +50,7 @@ class ObservationRegistryConfigurer { ObservationRegistryConfigurer(ObjectProvider> customizers, ObjectProvider observationPredicates, - ObjectProvider> tagProviders, + ObjectProvider> tagProviders, ObjectProvider> observationHandlers, ObjectProvider observationHandlerGrouping) { this.customizers = customizers; @@ -79,7 +79,7 @@ private void registerObservationPredicates(ObservationRegistry registry) { private void registerGlobalTagsProvider(ObservationRegistry registry) { this.tagProviders.orderedStream() - .forEach((tagProvider) -> registry.observationConfig().tagsProvider(tagProvider)); + .forEach((tagProvider) -> registry.observationConfig().keyValuesProvider(tagProvider)); } @SuppressWarnings("unchecked") diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryPostProcessor.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryPostProcessor.java index c3404c1fd8f1..baa1ca0d3374 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryPostProcessor.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryPostProcessor.java @@ -16,7 +16,7 @@ package org.springframework.boot.actuate.autoconfigure.observation; -import io.micrometer.observation.Observation.GlobalTagsProvider; +import io.micrometer.observation.Observation.GlobalKeyValuesProvider; import io.micrometer.observation.ObservationHandler; import io.micrometer.observation.ObservationPredicate; import io.micrometer.observation.ObservationRegistry; @@ -38,7 +38,7 @@ class ObservationRegistryPostProcessor implements BeanPostProcessor { private final ObjectProvider observationPredicates; - private final ObjectProvider> tagProviders; + private final ObjectProvider> tagProviders; private final ObjectProvider> observationHandlers; @@ -48,7 +48,7 @@ class ObservationRegistryPostProcessor implements BeanPostProcessor { ObservationRegistryPostProcessor(ObjectProvider> observationRegistryCustomizers, ObjectProvider observationPredicates, - ObjectProvider> tagProviders, + ObjectProvider> tagProviders, ObjectProvider> observationHandlers, ObjectProvider observationHandlerGrouping) { this.observationRegistryCustomizers = observationRegistryCustomizers; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java new file mode 100644 index 000000000000..e084680152af --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java @@ -0,0 +1,129 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing; + +import java.util.List; + +import brave.Tracing; +import brave.Tracing.Builder; +import brave.TracingCustomizer; +import brave.handler.SpanHandler; +import brave.propagation.B3Propagation; +import brave.propagation.CurrentTraceContext; +import brave.propagation.CurrentTraceContext.ScopeDecorator; +import brave.propagation.CurrentTraceContextCustomizer; +import brave.propagation.Propagation.Factory; +import brave.propagation.ThreadLocalCurrentTraceContext; +import brave.sampler.Sampler; +import io.micrometer.tracing.brave.bridge.BraveBaggageManager; +import io.micrometer.tracing.brave.bridge.BraveCurrentTraceContext; +import io.micrometer.tracing.brave.bridge.BraveTracer; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Brave. + * + * @author Moritz Halbritter + * @since 3.0.0 + */ +@AutoConfiguration(before = MicrometerTracingAutoConfiguration.class) +@ConditionalOnClass(brave.Tracer.class) +@EnableConfigurationProperties(TracingProperties.class) +public class BraveAutoConfiguration { + + /** + * Default value for application name if {@code spring.application.name} is not set. + */ + private static final String DEFAULT_APPLICATION_NAME = "application"; + + @Bean + @ConditionalOnMissingBean + public Tracing braveTracing(Environment environment, List spanHandlers, + List tracingCustomizers, CurrentTraceContext currentTraceContext, + Factory propagationFactory, Sampler sampler) { + String applicationName = environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME); + Builder builder = Tracing.newBuilder().currentTraceContext(currentTraceContext) + .propagationFactory(propagationFactory).sampler(sampler).localServiceName(applicationName); + for (SpanHandler spanHandler : spanHandlers) { + builder.addSpanHandler(spanHandler); + } + for (TracingCustomizer tracingCustomizer : tracingCustomizers) { + tracingCustomizer.customize(builder); + } + return builder.build(); + } + + @Bean + @ConditionalOnMissingBean + public brave.Tracer braveTracer(Tracing tracing) { + return tracing.tracer(); + } + + @Bean + @ConditionalOnMissingBean + public CurrentTraceContext braveCurrentTraceContext(List scopeDecorators, + List currentTraceContextCustomizers) { + ThreadLocalCurrentTraceContext.Builder builder = ThreadLocalCurrentTraceContext.newBuilder(); + for (ScopeDecorator scopeDecorator : scopeDecorators) { + builder.addScopeDecorator(scopeDecorator); + } + for (CurrentTraceContextCustomizer currentTraceContextCustomizer : currentTraceContextCustomizers) { + currentTraceContextCustomizer.customize(builder); + } + return builder.build(); + } + + @Bean + @ConditionalOnMissingBean + public Factory bravePropagationFactory() { + return B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build(); + } + + @Bean + @ConditionalOnMissingBean + public Sampler braveSampler(TracingProperties properties) { + return Sampler.create(properties.getSampling().getProbability()); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(BraveTracer.class) + static class BraveMicrometer { + + @Bean + @ConditionalOnMissingBean + BraveTracer braveTracerBridge(brave.Tracer tracer, CurrentTraceContext currentTraceContext, + BraveBaggageManager braveBaggageManager) { + return new BraveTracer(tracer, new BraveCurrentTraceContext(currentTraceContext), braveBaggageManager); + } + + @Bean + @ConditionalOnMissingBean + BraveBaggageManager braveBaggageManager() { + return new BraveBaggageManager(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfiguration.java new file mode 100644 index 000000000000..5d279b54c2f5 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfiguration.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing; + +import io.micrometer.tracing.Tracer; +import io.micrometer.tracing.handler.DefaultTracingObservationHandler; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for the Micrometer Tracing API. + * + * @author Moritz Halbritter + * @since 3.0.0 + */ +@AutoConfiguration +@ConditionalOnClass(Tracer.class) +public class MicrometerTracingAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnBean(Tracer.class) + public DefaultTracingObservationHandler defaultTracingObservationHandler(Tracer tracer) { + return new DefaultTracingObservationHandler(tracer); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfiguration.java new file mode 100644 index 000000000000..006eaf39b658 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfiguration.java @@ -0,0 +1,39 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing; + +import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.MicrometerConfiguration; +import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.SdkConfiguration; +import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.TracerConfiguration; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.Import; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for OpenTelemetry. + * + * It uses imports on {@link OpenTelemetryConfigurations} to guarantee the correct + * configuration ordering. + * + * @author Moritz Halbritter + * @since 3.0.0 + */ +@AutoConfiguration(before = MicrometerTracingAutoConfiguration.class) +@Import({ SdkConfiguration.class, TracerConfiguration.class, MicrometerConfiguration.class }) +public class OpenTelemetryAutoConfiguration { + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurations.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurations.java new file mode 100644 index 000000000000..fe95f30916ad --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurations.java @@ -0,0 +1,151 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing; + +import java.util.List; +import java.util.stream.Collectors; + +import io.micrometer.tracing.otel.bridge.OtelBaggageManager; +import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext; +import io.micrometer.tracing.otel.bridge.OtelTracer; +import io.micrometer.tracing.otel.bridge.OtelTracer.EventPublisher; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.propagation.ContextPropagators; +import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; +import io.opentelemetry.sdk.trace.SpanProcessor; +import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; +import io.opentelemetry.sdk.trace.export.SpanExporter; +import io.opentelemetry.sdk.trace.samplers.Sampler; +import io.opentelemetry.semconv.resource.attributes.ResourceAttributes; + +import org.springframework.boot.SpringBootVersion; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; + +/** + * Configurations for Open Telemetry. Those are imported by + * {@link OpenTelemetryAutoConfiguration}. + * + * @author Moritz Halbritter + */ +class OpenTelemetryConfigurations { + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(SdkTracerProvider.class) + @EnableConfigurationProperties(TracingProperties.class) + static class SdkConfiguration { + + /** + * Default value for application name if {@code spring.application.name} is not + * set. + */ + private static final String DEFAULT_APPLICATION_NAME = "application"; + + @Bean + @ConditionalOnMissingBean + OpenTelemetry openTelemetry(SdkTracerProvider sdkTracerProvider, ContextPropagators contextPropagators) { + return OpenTelemetrySdk.builder().setTracerProvider(sdkTracerProvider).setPropagators(contextPropagators) + .build(); + } + + @Bean + @ConditionalOnMissingBean + SdkTracerProvider otelSdkTracerProvider(Environment environment, List spanProcessors, + Sampler sampler) { + String applicationName = environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME); + SdkTracerProviderBuilder builder = SdkTracerProvider.builder().setSampler(sampler) + .setResource(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, applicationName))); + for (SpanProcessor spanProcessor : spanProcessors) { + builder.addSpanProcessor(spanProcessor); + } + return builder.build(); + } + + @Bean + @ConditionalOnMissingBean + ContextPropagators otelContextPropagators(List textMapPropagators) { + return ContextPropagators.create(TextMapPropagator.composite(textMapPropagators)); + } + + @Bean + @ConditionalOnMissingBean + Sampler otelSampler(TracingProperties properties) { + return Sampler.traceIdRatioBased(properties.getSampling().getProbability()); + } + + @Bean + @ConditionalOnMissingBean + SpanProcessor otelSpanProcessor(List spanExporter) { + return SpanProcessor.composite(spanExporter.stream() + .map((exporter) -> BatchSpanProcessor.builder(exporter).build()).collect(Collectors.toList())); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(Tracer.class) + static class TracerConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnBean(OpenTelemetry.class) + Tracer otelTracer(OpenTelemetry openTelemetry) { + return openTelemetry.getTracer("org.springframework.boot", SpringBootVersion.getVersion()); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(OtelTracer.class) + static class MicrometerConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnBean(Tracer.class) + OtelTracer micrometerOtelTracer(Tracer tracer, EventPublisher eventPublisher, + OtelCurrentTraceContext otelCurrentTraceContext) { + return new OtelTracer(tracer, otelCurrentTraceContext, eventPublisher, + new OtelBaggageManager(otelCurrentTraceContext, List.of(), List.of())); + } + + @Bean + @ConditionalOnMissingBean + EventPublisher otelTracerEventPublisher() { + return (event) -> { + }; + } + + @Bean + @ConditionalOnMissingBean + OtelCurrentTraceContext otelCurrentTraceContext() { + return new OtelCurrentTraceContext(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/TracingProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/TracingProperties.java new file mode 100644 index 000000000000..56ce52a93a5a --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/TracingProperties.java @@ -0,0 +1,56 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Configuration properties for tracing. + * + * @author Moritz Halbritter + * @since 3.0.0 + */ +@ConfigurationProperties("management.tracing") +public class TracingProperties { + + /** + * Sampling configuration. + */ + private final Sampling sampling = new Sampling(); + + public Sampling getSampling() { + return this.sampling; + } + + public static class Sampling { + + /** + * Probability in the range from 0.0 to 1.0 that a trace will be sampled. + */ + private float probability = 0.10f; + + public float getProbability() { + return this.probability; + } + + public void setProbability(float probability) { + this.probability = probability; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/package-info.java new file mode 100644 index 000000000000..64e6f7cad706 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-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. + */ + +/** + * Auto-configuration for Micrometer Tracing. + */ +package org.springframework.boot.actuate.autoconfigure.tracing; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/MeterRegistrySpanMetrics.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/MeterRegistrySpanMetrics.java new file mode 100644 index 000000000000..1f9d4e0325e3 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/MeterRegistrySpanMetrics.java @@ -0,0 +1,73 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing.wavefront; + +import java.util.concurrent.BlockingQueue; + +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.tracing.reporter.wavefront.SpanMetrics; + +/** + * Bridges {@link SpanMetrics} to a {@link MeterRegistry}. + * + * @author Moritz Halbritter + */ +class MeterRegistrySpanMetrics implements SpanMetrics { + + private final Counter spansReceived; + + private final Counter spansDropped; + + private final Counter reportErrors; + + private final MeterRegistry meterRegistry; + + MeterRegistrySpanMetrics(MeterRegistry meterRegistry) { + this.meterRegistry = meterRegistry; + this.spansReceived = meterRegistry.counter("wavefront.reporter.spans.received"); + this.spansDropped = meterRegistry.counter("wavefront.reporter.spans.dropped"); + this.reportErrors = meterRegistry.counter("wavefront.reporter.errors"); + } + + @Override + public void reportDropped() { + this.spansDropped.increment(); + } + + @Override + public void reportReceived() { + this.spansReceived.increment(); + } + + @Override + public void reportErrors() { + this.reportErrors.increment(); + } + + @Override + public void registerQueueSize(BlockingQueue queue) { + this.meterRegistry.gauge("wavefront.reporter.queue.size", queue, (q) -> (double) q.size()); + } + + @Override + public void registerQueueRemainingCapacity(BlockingQueue queue) { + this.meterRegistry.gauge("wavefront.reporter.queue.remaining_capacity", queue, + (q) -> (double) q.remainingCapacity()); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfiguration.java new file mode 100644 index 000000000000..9eea91397ac4 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfiguration.java @@ -0,0 +1,136 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing.wavefront; + +import java.util.Set; + +import brave.handler.SpanHandler; +import com.wavefront.sdk.common.WavefrontSender; +import com.wavefront.sdk.common.application.ApplicationTags; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.tracing.reporter.wavefront.SpanMetrics; +import io.micrometer.tracing.reporter.wavefront.WavefrontBraveSpanHandler; +import io.micrometer.tracing.reporter.wavefront.WavefrontOtelSpanHandler; +import io.micrometer.tracing.reporter.wavefront.WavefrontSpanHandler; +import io.opentelemetry.sdk.trace.export.SpanExporter; + +import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties; +import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties.Tracing; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Wavefront. + * + * @author Moritz Halbritter + * @since 3.0.0 + */ +@AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class, + WavefrontAutoConfiguration.class }) +@EnableConfigurationProperties(WavefrontProperties.class) +@ConditionalOnBean(WavefrontSender.class) +public class WavefrontTracingAutoConfiguration { + + /** + * Default value for application name if {@code spring.application.name} is not set. + */ + private static final String DEFAULT_APPLICATION_NAME = "application"; + + @Bean + @ConditionalOnMissingBean + public ApplicationTags applicationTags(Environment environment, WavefrontProperties properties) { + String springApplicationName = environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME); + Tracing tracing = properties.getTracing(); + String applicationName = (tracing.getApplicationName() != null) ? tracing.getApplicationName() + : springApplicationName; + String serviceName = (tracing.getServiceName() != null) ? tracing.getServiceName() : springApplicationName; + return new ApplicationTags.Builder(applicationName, serviceName).build(); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(WavefrontSpanHandler.class) + static class WavefrontMicrometer { + + @Bean + @ConditionalOnMissingBean + WavefrontSpanHandler wavefrontSpanHandler(WavefrontProperties properties, WavefrontSender wavefrontSender, + SpanMetrics spanMetrics, ApplicationTags applicationTags) { + return new WavefrontSpanHandler(properties.getSender().getMaxQueueSize(), wavefrontSender, spanMetrics, + properties.getSourceOrDefault(), applicationTags, Set.of()); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnBean(MeterRegistry.class) + static class MeterRegistrySpanMetricsConfiguration { + + @Bean + @ConditionalOnMissingBean + MeterRegistrySpanMetrics meterRegistrySpanMetrics(MeterRegistry meterRegistry) { + return new MeterRegistrySpanMetrics(meterRegistry); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnMissingBean(MeterRegistry.class) + static class NoopSpanMetricsConfiguration { + + @Bean + @ConditionalOnMissingBean + SpanMetrics meterRegistrySpanMetrics() { + return SpanMetrics.NOOP; + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(SpanHandler.class) + static class WavefrontBrave { + + @Bean + @ConditionalOnMissingBean + WavefrontBraveSpanHandler wavefrontBraveSpanHandler(WavefrontSpanHandler wavefrontSpanHandler) { + return new WavefrontBraveSpanHandler(wavefrontSpanHandler); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(SpanExporter.class) + static class WavefrontOpenTelemetry { + + @Bean + @ConditionalOnMissingBean + WavefrontOtelSpanHandler wavefrontOtelSpanHandler(WavefrontSpanHandler wavefrontSpanHandler) { + return new WavefrontOtelSpanHandler(wavefrontSpanHandler); + } + + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/package-info.java new file mode 100644 index 000000000000..5ded81bd8e2f --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-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. + */ + +/** + * Auto-configuration for tracing with Wavefront. + */ +package org.springframework.boot.actuate.autoconfigure.tracing.wavefront; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfiguration.java new file mode 100644 index 000000000000..89862e4e6635 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfiguration.java @@ -0,0 +1,57 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; + +import zipkin2.Span; +import zipkin2.codec.BytesEncoder; +import zipkin2.codec.SpanBytesEncoder; +import zipkin2.reporter.Sender; + +import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.BraveConfiguration; +import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.OpenTelemetryConfiguration; +import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.ReporterConfiguration; +import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.SenderConfiguration; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Zipkin. + * + * It uses imports on {@link ZipkinConfigurations} to guarantee the correct configuration + * ordering. + * + * @author Moritz Halbritter + * @since 3.0.0 + */ +@AutoConfiguration(after = RestTemplateAutoConfiguration.class) +@ConditionalOnClass(Sender.class) +@Import({ SenderConfiguration.class, ReporterConfiguration.class, BraveConfiguration.class, + OpenTelemetryConfiguration.class }) +public class ZipkinAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + public BytesEncoder spanBytesEncoder() { + return SpanBytesEncoder.JSON_V2; + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java new file mode 100644 index 000000000000..cd7c96347fec --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java @@ -0,0 +1,109 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; + +import brave.handler.SpanHandler; +import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; +import zipkin2.Span; +import zipkin2.codec.BytesEncoder; +import zipkin2.reporter.AsyncReporter; +import zipkin2.reporter.Reporter; +import zipkin2.reporter.Sender; +import zipkin2.reporter.brave.ZipkinSpanHandler; +import zipkin2.reporter.urlconnection.URLConnectionSender; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +/** + * Configurations for Zipkin. Those are imported by {@link ZipkinAutoConfiguration}. + * + * @author Moritz Halbritter + */ +class ZipkinConfigurations { + + @Configuration(proxyBeanMethods = false) + @EnableConfigurationProperties(ZipkinProperties.class) + static class SenderConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnClass(URLConnectionSender.class) + Sender urlConnectionSender(ZipkinProperties properties) { + return URLConnectionSender.newBuilder().connectTimeout((int) properties.getConnectTimeout().getSeconds()) + .readTimeout((int) properties.getReadTimeout().getSeconds()).endpoint(properties.getEndpoint()) + .build(); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnBean(RestTemplateBuilder.class) + @ConditionalOnMissingClass("zipkin2.reporter.urlconnection.URLConnectionSender") + Sender restTemplateSender(ZipkinProperties properties, RestTemplateBuilder restTemplateBuilder) { + RestTemplate restTemplate = restTemplateBuilder.setConnectTimeout(properties.getConnectTimeout()) + .setReadTimeout(properties.getReadTimeout()).build(); + return new ZipkinRestTemplateSender(properties.getEndpoint(), restTemplate); + } + + } + + @Configuration(proxyBeanMethods = false) + static class ReporterConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnBean(Sender.class) + Reporter spanReporter(Sender sender, BytesEncoder encoder) { + return AsyncReporter.builder(sender).build(encoder); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(ZipkinSpanHandler.class) + static class BraveConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnBean(Reporter.class) + SpanHandler zipkinSpanHandler(Reporter spanReporter) { + return ZipkinSpanHandler.newBuilder(spanReporter).build(); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(ZipkinSpanExporter.class) + static class OpenTelemetryConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnBean(Sender.class) + ZipkinSpanExporter zipkinSpanExporter(BytesEncoder encoder, Sender sender) { + return ZipkinSpanExporter.builder().setEncoder(encoder).setSender(sender).build(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinProperties.java new file mode 100644 index 000000000000..088ae8ee42b1 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinProperties.java @@ -0,0 +1,71 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; + +import java.time.Duration; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Configuration properties for {@link ZipkinAutoConfiguration}. + * + * @author Moritz Halbritter + * @since 3.0.0 + */ +@ConfigurationProperties("management.zipkin.tracing") +public class ZipkinProperties { + + /** + * URL to the Zipkin API. + */ + private String endpoint = "http://localhost:9411/api/v2/spans"; + + /** + * Connection timeout for requests to Zipkin. + */ + private Duration connectTimeout = Duration.ofSeconds(1); + + /** + * Read timeout for requests to Zipkin. + */ + private Duration readTimeout = Duration.ofSeconds(10); + + public String getEndpoint() { + return this.endpoint; + } + + public void setEndpoint(String endpoint) { + this.endpoint = endpoint; + } + + public Duration getConnectTimeout() { + return this.connectTimeout; + } + + public void setConnectTimeout(Duration connectTimeout) { + this.connectTimeout = connectTimeout; + } + + public Duration getReadTimeout() { + return this.readTimeout; + } + + public void setReadTimeout(Duration readTimeout) { + this.readTimeout = readTimeout; + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSender.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSender.java new file mode 100644 index 000000000000..c3fea73f761f --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSender.java @@ -0,0 +1,170 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.List; +import java.util.zip.GZIPOutputStream; + +import zipkin2.Call; +import zipkin2.Callback; +import zipkin2.CheckResult; +import zipkin2.codec.Encoding; +import zipkin2.reporter.BytesMessageEncoder; +import zipkin2.reporter.ClosedSenderException; +import zipkin2.reporter.Sender; + +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.util.unit.DataSize; +import org.springframework.web.client.RestTemplate; + +/** + * A Zipkin {@link Sender} which uses {@link RestTemplate} for HTTP communication. + * Supports automatic compression with gzip. + * + * @author Moritz Halbritter + */ +class ZipkinRestTemplateSender extends Sender { + + private static final DataSize MESSAGE_MAX_BYTES = DataSize.ofKilobytes(512); + + private final String endpoint; + + private final RestTemplate restTemplate; + + private volatile boolean closed; + + ZipkinRestTemplateSender(String endpoint, RestTemplate restTemplate) { + this.endpoint = endpoint; + this.restTemplate = restTemplate; + } + + @Override + public Encoding encoding() { + return Encoding.JSON; + } + + @Override + public int messageMaxBytes() { + return (int) MESSAGE_MAX_BYTES.toBytes(); + } + + @Override + public int messageSizeInBytes(List encodedSpans) { + return encoding().listSizeInBytes(encodedSpans); + } + + @Override + public int messageSizeInBytes(int encodedSizeInBytes) { + return encoding().listSizeInBytes(encodedSizeInBytes); + } + + @Override + public Call sendSpans(List encodedSpans) { + if (this.closed) { + throw new ClosedSenderException(); + } + return new HttpCall(this.endpoint, BytesMessageEncoder.JSON.encode(encodedSpans), this.restTemplate); + } + + @Override + public CheckResult check() { + try { + sendSpans(List.of()).execute(); + return CheckResult.OK; + } + catch (IOException | RuntimeException ex) { + return CheckResult.failed(ex); + } + } + + @Override + public void close() throws IOException { + this.closed = true; + } + + private static class HttpCall extends Call.Base { + + /** + * Only use gzip compression on data which is bigger than this in bytes. + */ + private static final DataSize COMPRESSION_THRESHOLD = DataSize.ofKilobytes(1); + + private final String endpoint; + + private final byte[] body; + + private final RestTemplate restTemplate; + + HttpCall(String endpoint, byte[] body, RestTemplate restTemplate) { + this.endpoint = endpoint; + this.body = body; + this.restTemplate = restTemplate; + } + + @Override + protected Void doExecute() throws IOException { + HttpHeaders headers = new HttpHeaders(); + headers.set("b3", "0"); + headers.set("Content-Type", "application/json"); + byte[] body; + if (needsCompression(this.body)) { + headers.set("Content-Encoding", "gzip"); + body = compress(this.body); + } + else { + body = this.body; + } + HttpEntity request = new HttpEntity<>(body, headers); + this.restTemplate.exchange(this.endpoint, HttpMethod.POST, request, Void.class); + return null; + } + + private boolean needsCompression(byte[] body) { + return body.length > COMPRESSION_THRESHOLD.toBytes(); + } + + @Override + protected void doEnqueue(Callback callback) { + try { + doExecute(); + callback.onSuccess(null); + } + catch (IOException | RuntimeException ex) { + callback.onError(ex); + } + } + + @Override + public Call clone() { + return new HttpCall(this.endpoint, this.body, this.restTemplate); + } + + private byte[] compress(byte[] input) throws IOException { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try (GZIPOutputStream gzip = new GZIPOutputStream(result)) { + gzip.write(input); + } + return result.toByteArray(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/package-info.java new file mode 100644 index 000000000000..10dc7a7e8663 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-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. + */ + +/** + * Auto-configuration for tracing with Zipkin. + */ +package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfiguration.java new file mode 100644 index 000000000000..e6e044f71fc5 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfiguration.java @@ -0,0 +1,61 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.wavefront; + +import java.time.Duration; + +import com.wavefront.sdk.common.WavefrontSender; +import com.wavefront.sdk.common.clients.WavefrontClient.Builder; + +import org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront.WavefrontMetricsExportAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.tracing.wavefront.WavefrontTracingAutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.context.annotation.Bean; +import org.springframework.util.unit.DataSize; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Wavefront common infrastructure. + * Metrics are auto-configured in {@link WavefrontMetricsExportAutoConfiguration}, tracing + * is auto-configured in {@link WavefrontTracingAutoConfiguration}. + * + * @author Moritz Halbritter + * @since 3.0.0 + */ +@AutoConfiguration +@ConditionalOnClass(WavefrontSender.class) +@EnableConfigurationProperties(WavefrontProperties.class) +public class WavefrontAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + public WavefrontSender wavefrontSender(WavefrontProperties properties) { + Builder builder = new Builder(properties.getEffectiveUri().toString(), properties.getApiTokenOrThrow()); + PropertyMapper mapper = PropertyMapper.get().alwaysApplyingWhenNonNull(); + WavefrontProperties.Sender sender = properties.getSender(); + mapper.from(sender.getMaxQueueSize()).to(builder::maxQueueSize); + mapper.from(sender.getFlushInterval()).asInt(Duration::getSeconds).to(builder::flushIntervalSeconds); + mapper.from(sender.getMessageSize()).asInt(DataSize::toBytes).to(builder::messageSizeBytes); + mapper.from(sender.getBatchSize()).to(builder::batchSize); + return builder.build(); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontProperties.java new file mode 100644 index 000000000000..33576b4af9ea --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontProperties.java @@ -0,0 +1,290 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.wavefront; + +import java.net.InetAddress; +import java.net.URI; +import java.net.UnknownHostException; +import java.time.Duration; + +import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PushRegistryProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException; +import org.springframework.util.unit.DataSize; + +/** + * Configuration properties to configure Wavefront. + * + * @author Moritz Halbritter + * @since 3.0.0 + */ +@ConfigurationProperties(prefix = "management.wavefront") +public class WavefrontProperties { + + /** + * URI to ship metrics and traces to. + */ + private URI uri = URI.create("https://longboard.wavefront.com"); + + /** + * Unique identifier for the app instance that is the source of metrics being + * published to Wavefront. Defaults to the local host name. + */ + private String source; + + /** + * API token used when publishing metrics directly to the Wavefront API host. + */ + private String apiToken; + + /** + * Sender configuration. + */ + private final Sender sender = new Sender(); + + /** + * Metrics configuration. + */ + private final Metrics metrics = new Metrics(); + + /** + * Tracing configuration. + */ + private final Tracing tracing = new Tracing(); + + public Sender getSender() { + return this.sender; + } + + public Metrics getMetrics() { + return this.metrics; + } + + public Tracing getTracing() { + return this.tracing; + } + + public URI getUri() { + return this.uri; + } + + public void setUri(URI uri) { + this.uri = uri; + } + + public String getSource() { + return this.source; + } + + public void setSource(String source) { + this.source = source; + } + + public String getApiToken() { + return this.apiToken; + } + + public void setApiToken(String apiToken) { + this.apiToken = apiToken; + } + + /** + * Returns the effective URI of the wavefront instance. This will not be the same URI + * given through {@link #setUri(URI)} when a proxy is used. + * @return the effective URI of the wavefront instance + */ + public URI getEffectiveUri() { + if (usesProxy()) { + // See io.micrometer.wavefront.WavefrontMeterRegistry.getWavefrontReportingUri + return URI.create(this.uri.toString().replace("proxy://", "http://")); + } + return this.uri; + } + + /** + * Returns the API token or throws an exception if the API token is mandatory. If a + * proxy is used, the API token is optional. + * @return the API token + */ + public String getApiTokenOrThrow() { + if (this.apiToken == null && !usesProxy()) { + throw new InvalidConfigurationPropertyValueException("management.wavefront.api-token", null, + "This property is mandatory whenever publishing directly to the Wavefront API"); + } + return this.apiToken; + } + + public String getSourceOrDefault() { + if (this.source != null) { + return this.source; + } + return getSourceDefault(); + } + + private String getSourceDefault() { + try { + return InetAddress.getLocalHost().getHostName(); + } + catch (UnknownHostException ex) { + return "unknown"; + } + } + + private boolean usesProxy() { + return "proxy".equals(this.uri.getScheme()); + } + + public static class Sender { + + /** + * Maximum size of queued messages. + */ + private int maxQueueSize = 50000; + + /** + * Flush interval to send queued messages. + */ + private Duration flushInterval = Duration.ofSeconds(1); + + /** + * Maximum size of a message. + */ + private DataSize messageSize = DataSize.ofBytes(Integer.MAX_VALUE); + + /** + * Number of measurements per request to use for Wavefront. If more measurements + * are found, then multiple requests will be made. + */ + private int batchSize = 10000; + + public int getMaxQueueSize() { + return this.maxQueueSize; + } + + public void setMaxQueueSize(int maxQueueSize) { + this.maxQueueSize = maxQueueSize; + } + + public Duration getFlushInterval() { + return this.flushInterval; + } + + public void setFlushInterval(Duration flushInterval) { + this.flushInterval = flushInterval; + } + + public DataSize getMessageSize() { + return this.messageSize; + } + + public void setMessageSize(DataSize messageSize) { + this.messageSize = messageSize; + } + + public int getBatchSize() { + return this.batchSize; + } + + public void setBatchSize(int batchSize) { + this.batchSize = batchSize; + } + + } + + public static class Metrics { + + /** + * Export configuration. + */ + private Export export = new Export(); + + public Export getExport() { + return this.export; + } + + public void setExport(Export export) { + this.export = export; + } + + public static class Export extends PushRegistryProperties { + + /** + * Global prefix to separate metrics originating from this app's + * instrumentation from those originating from other Wavefront integrations + * when viewed in the Wavefront UI. + */ + private String globalPrefix; + + public String getGlobalPrefix() { + return this.globalPrefix; + } + + public void setGlobalPrefix(String globalPrefix) { + this.globalPrefix = globalPrefix; + } + + /** + * See {@link PushRegistryProperties#getBatchSize()}. + */ + @Override + public Integer getBatchSize() { + throw new UnsupportedOperationException("Use Sender.getBatchSize() instead"); + } + + /** + * See {@link PushRegistryProperties#setBatchSize(Integer)}. + */ + @Override + public void setBatchSize(Integer batchSize) { + throw new UnsupportedOperationException("Use Sender.setBatchSize(int) instead"); + } + + } + + } + + public static class Tracing { + + /** + * Application name. Defaults to 'spring.application.name'. + */ + private String applicationName; + + /** + * Service name. Defaults to 'spring.application.name'. + */ + private String serviceName; + + public String getServiceName() { + return this.serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public String getApplicationName() { + return this.applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/package-info.java new file mode 100644 index 000000000000..213eb6cccf64 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-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. + */ + +/** + * Classes shared between Wavefront tracing and metrics. + */ +package org.springframework.boot.actuate.autoconfigure.wavefront; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/LocalManagementPort.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/LocalManagementPort.java index 01e5213e1019..e4404b9d9976 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/LocalManagementPort.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/LocalManagementPort.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -28,7 +28,8 @@ * Annotation at the field or method/constructor parameter level that injects the HTTP * management port that got allocated at runtime. Provides a convenient alternative for * @Value("${local.management.port}"). - * + * @deprecated since 2.7.0 for removal in 2.9.0 in favor of + * {@code org.springframework.boot.test.web.server.LocalManagementPort} * @author Stephane Nicoll * @since 2.0.0 */ @@ -36,6 +37,7 @@ @Retention(RetentionPolicy.RUNTIME) @Documented @Value("${local.management.port}") +@Deprecated public @interface LocalManagementPort { } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index a27a8a6940ff..316290f82b82 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -54,6 +54,12 @@ "sun.java.command" ] }, + { + "name": "management.endpoint.health.probes.add-additional-paths", + "type": "java.lang.Boolean", + "description": "Whether to make the liveness and readiness health groups available on the main server port.", + "defaultValue": false + }, { "name": "management.endpoint.health.probes.enabled", "type": "java.lang.Boolean", @@ -1826,7 +1832,7 @@ "type": "java.lang.String", "deprecation": { "level": "error", - "replacement": "management.wavefront.metrics.export.api-token" + "replacement": "management.wavefront.api-token" } }, { @@ -1834,7 +1840,7 @@ "type": "java.lang.Integer", "deprecation": { "level": "error", - "replacement": "management.wavefront.metrics.export.batch-size" + "replacement": "management.wavefront.sender.batch-size" } }, { @@ -1879,7 +1885,7 @@ "type": "java.time.Duration", "deprecation": { "level": "error", - "replacement": "management.wavefront.metrics.export.sender.flush-interval" + "replacement": "management.wavefront.sender.flush-interval" } }, { @@ -1887,7 +1893,7 @@ "type": "java.lang.Integer", "deprecation": { "level": "error", - "replacement": "management.wavefront.metrics.export.sender.max-queue-size" + "replacement": "management.wavefront.sender.max-queue-size" } }, { @@ -1895,7 +1901,7 @@ "type": "org.springframework.util.unit.DataSize", "deprecation": { "level": "error", - "replacement": "management.wavefront.metrics.export.sender.message-size" + "replacement": "management.wavefront.sender.message-size" } }, { @@ -1903,7 +1909,7 @@ "type": "java.lang.String", "deprecation": { "level": "error", - "replacement": "management.wavefront.metrics.export.source" + "replacement": "management.wavefront.source" } }, { @@ -1919,7 +1925,7 @@ "type": "java.net.URI", "deprecation": { "level": "error", - "replacement": "management.wavefront.metrics.export.uri" + "replacement": "management.wavefront.uri" } }, { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 0ba704f63db8..cb999708e2c5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -95,6 +95,12 @@ org.springframework.boot.actuate.autoconfigure.startup.StartupEndpointAutoConfig org.springframework.boot.actuate.autoconfigure.system.DiskSpaceHealthContributorAutoConfiguration org.springframework.boot.actuate.autoconfigure.trace.http.HttpTraceAutoConfiguration org.springframework.boot.actuate.autoconfigure.trace.http.HttpTraceEndpointAutoConfiguration +org.springframework.boot.actuate.autoconfigure.tracing.BraveAutoConfiguration +org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingAutoConfiguration +org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryAutoConfiguration +org.springframework.boot.actuate.autoconfigure.tracing.wavefront.WavefrontTracingAutoConfiguration +org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinAutoConfiguration +org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontAutoConfiguration org.springframework.boot.actuate.autoconfigure.web.mappings.MappingsEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementContextAutoConfiguration org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java index fb5ec4725693..9996e2debea0 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -20,6 +20,8 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration; @@ -69,10 +71,11 @@ void testChild() { @Configuration @EnableAutoConfiguration(exclude = { ElasticsearchDataAutoConfiguration.class, ElasticsearchRepositoriesAutoConfiguration.class, CassandraAutoConfiguration.class, - CassandraDataAutoConfiguration.class, MongoDataAutoConfiguration.class, - MongoReactiveDataAutoConfiguration.class, Neo4jAutoConfiguration.class, Neo4jDataAutoConfiguration.class, - Neo4jRepositoriesAutoConfiguration.class, RedisAutoConfiguration.class, - RedisRepositoriesAutoConfiguration.class, FlywayAutoConfiguration.class, MetricsAutoConfiguration.class }) + CassandraDataAutoConfiguration.class, MicrometerTracingAutoConfiguration.class, + MongoDataAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class, Neo4jAutoConfiguration.class, + Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class, RedisAutoConfiguration.class, + RedisRepositoriesAutoConfiguration.class, FlywayAutoConfiguration.class, MetricsAutoConfiguration.class, + WavefrontAutoConfiguration.class }) static class Parent { } @@ -80,10 +83,11 @@ static class Parent { @Configuration @EnableAutoConfiguration(exclude = { ElasticsearchDataAutoConfiguration.class, ElasticsearchRepositoriesAutoConfiguration.class, CassandraAutoConfiguration.class, - CassandraDataAutoConfiguration.class, MongoDataAutoConfiguration.class, - MongoReactiveDataAutoConfiguration.class, Neo4jAutoConfiguration.class, Neo4jDataAutoConfiguration.class, - Neo4jRepositoriesAutoConfiguration.class, RedisAutoConfiguration.class, - RedisRepositoriesAutoConfiguration.class, FlywayAutoConfiguration.class, MetricsAutoConfiguration.class }) + CassandraDataAutoConfiguration.class, MicrometerTracingAutoConfiguration.class, + MongoDataAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class, Neo4jAutoConfiguration.class, + Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class, RedisAutoConfiguration.class, + RedisRepositoriesAutoConfiguration.class, FlywayAutoConfiguration.class, MetricsAutoConfiguration.class, + WavefrontAutoConfiguration.class }) static class Child { } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfigurationTests.java new file mode 100644 index 000000000000..5c1f4d9aa4c3 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfigurationTests.java @@ -0,0 +1,110 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.elasticsearch; + +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestClientBuilder; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; +import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestClientHealthIndicator; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ElasticSearchRestHealthContributorAutoConfiguration}. + * + * @author Filip Hrisafov + * @author Andy Wilkinson + */ +class ElasticSearchRestHealthContributorAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ElasticsearchRestClientAutoConfiguration.class, + ElasticSearchRestHealthContributorAutoConfiguration.class, + HealthContributorAutoConfiguration.class)); + + @Test + void runShouldCreateIndicator() { + this.contextRunner.run((context) -> assertThat(context) + .hasSingleBean(ElasticsearchRestClientHealthIndicator.class).hasBean("elasticsearchHealthContributor")); + } + + @Test + @SuppressWarnings("deprecation") + void runWithoutRestHighLevelClientAndWithoutRestClientShouldNotCreateIndicator() { + this.contextRunner + .withClassLoader( + new FilteredClassLoader(org.elasticsearch.client.RestHighLevelClient.class, RestClient.class)) + .run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestClientHealthIndicator.class) + .doesNotHaveBean("elasticsearchHealthContributor")); + } + + @Test + void runWithoutRestHighLevelClientAndWithRestClientShouldCreateIndicator() { + this.contextRunner.withUserConfiguration(CustomRestClientConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestClientHealthIndicator.class) + .hasBean("elasticsearchHealthContributor")); + } + + @Test + void runWithRestHighLevelClientAndWithRestClientShouldCreateIndicator() { + this.contextRunner.withUserConfiguration(CustomRestHighClientConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestClientHealthIndicator.class) + .hasBean("elasticsearchHealthContributor")); + } + + @Test + void runWhenDisabledShouldNotCreateIndicator() { + this.contextRunner.withPropertyValues("management.health.elasticsearch.enabled:false") + .run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestClientHealthIndicator.class) + .doesNotHaveBean("elasticsearchHealthContributor")); + } + + @Configuration(proxyBeanMethods = false) + static class CustomRestClientConfiguration { + + @Bean + RestClient customRestClient(RestClientBuilder builder) { + return builder.build(); + } + + } + + @Configuration(proxyBeanMethods = false) + @SuppressWarnings("deprecation") + static class CustomRestHighClientConfiguration { + + @Bean + org.elasticsearch.client.RestHighLevelClient customRestHighClient(RestClientBuilder builder) { + return new org.elasticsearch.client.RestHighLevelClient(builder); + } + + @Bean + RestClient customClient(org.elasticsearch.client.RestHighLevelClient restHighLevelClient) { + return restHighLevelClient.getLowLevelClient(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchReactiveHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchReactiveHealthContributorAutoConfigurationTests.java index c14fc96e4f62..7cf3bce2fc27 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchReactiveHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchReactiveHealthContributorAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-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. @@ -20,7 +20,7 @@ import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; import org.springframework.boot.actuate.elasticsearch.ElasticsearchReactiveHealthIndicator; -import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestHealthIndicator; +import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestClientHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration; import org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration; @@ -55,7 +55,7 @@ void runWithRegularIndicatorShouldOnlyCreateReactiveIndicator() { .withConfiguration(AutoConfigurations.of(ElasticSearchRestHealthContributorAutoConfiguration.class)) .run((context) -> assertThat(context).hasSingleBean(ElasticsearchReactiveHealthIndicator.class) .hasBean("elasticsearchHealthContributor") - .doesNotHaveBean(ElasticsearchRestHealthIndicator.class)); + .doesNotHaveBean(ElasticsearchRestClientHealthIndicator.class)); } @Test diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MappingsEndpointReactiveDocumentationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MappingsEndpointReactiveDocumentationTests.java index 7ae63277f911..6ecd2863f771 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MappingsEndpointReactiveDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MappingsEndpointReactiveDocumentationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -31,8 +31,8 @@ import org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MappingsEndpointServletDocumentationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MappingsEndpointServletDocumentationTests.java index 4055c9752ce8..b45f0ea735ee 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MappingsEndpointServletDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MappingsEndpointServletDocumentationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -33,8 +33,8 @@ import org.springframework.boot.actuate.web.mappings.servlet.ServletsMappingDescriptionProvider; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MetricsEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MetricsEndpointDocumentationTests.java index e46f761b8b95..6a179c35352f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MetricsEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MetricsEndpointDocumentationTests.java @@ -16,8 +16,8 @@ package org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation; -import io.micrometer.binder.jvm.JvmMemoryMetrics; import io.micrometer.core.instrument.Statistic; +import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/PrometheusScrapeEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/PrometheusScrapeEndpointDocumentationTests.java index a2df3d4446f6..128ff6033f17 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/PrometheusScrapeEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/PrometheusScrapeEndpointDocumentationTests.java @@ -16,8 +16,8 @@ package org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation; -import io.micrometer.binder.jvm.JvmMemoryMetrics; import io.micrometer.core.instrument.Clock; +import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; import io.micrometer.prometheus.PrometheusMeterRegistry; import io.prometheus.client.CollectorRegistry; import io.prometheus.client.exporter.common.TextFormat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java index c25193341f45..c945ccc5769d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -20,6 +20,9 @@ import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.tracing.BraveAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontAutoConfiguration; import org.springframework.boot.actuate.health.HealthEndpointWebExtension; import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -80,7 +83,8 @@ private ReactiveWebApplicationContextRunner reactiveWebRunner() { MongoReactiveAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class, RepositoryRestMvcAutoConfiguration.class, HazelcastAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class, SolrAutoConfiguration.class, RedisAutoConfiguration.class, - RedisRepositoriesAutoConfiguration.class, MetricsAutoConfiguration.class }) + RedisRepositoriesAutoConfiguration.class, MetricsAutoConfiguration.class, WavefrontAutoConfiguration.class, + BraveAutoConfiguration.class, OpenTelemetryAutoConfiguration.class }) @SpringBootConfiguration static class WebEndpointTestApplication { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfigurationTests.java index 117819206805..ecb3a5ad2ad5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfigurationTests.java @@ -16,11 +16,11 @@ package org.springframework.boot.actuate.autoconfigure.metrics; -import io.micrometer.binder.jvm.ClassLoaderMetrics; -import io.micrometer.binder.jvm.JvmGcMetrics; -import io.micrometer.binder.jvm.JvmHeapPressureMetrics; -import io.micrometer.binder.jvm.JvmMemoryMetrics; -import io.micrometer.binder.jvm.JvmThreadMetrics; +import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics; +import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics; +import io.micrometer.core.instrument.binder.jvm.JvmHeapPressureMetrics; +import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; +import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics; import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests.java index 3e79aa996a9b..2e9a10bdb743 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests.java @@ -16,7 +16,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics; -import io.micrometer.binder.logging.Log4j2Metrics; +import io.micrometer.core.instrument.binder.logging.Log4j2Metrics; import org.apache.logging.log4j.LogManager; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java index 87c99a8191a5..102618665834 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java @@ -16,7 +16,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics; -import io.micrometer.binder.logging.Log4j2Metrics; +import io.micrometer.core.instrument.binder.logging.Log4j2Metrics; import org.apache.logging.log4j.LogManager; import org.apache.logging.slf4j.SLF4JLoggerContext; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfigurationTests.java index 86fa5d08519e..b8c38301834a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfigurationTests.java @@ -16,7 +16,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics; -import io.micrometer.binder.logging.LogbackMetrics; +import io.micrometer.core.instrument.binder.logging.LogbackMetrics; import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationWithLog4j2AndLogbackTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationWithLog4j2AndLogbackTests.java index 4790f8c00e91..7570c896c915 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationWithLog4j2AndLogbackTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationWithLog4j2AndLogbackTests.java @@ -16,7 +16,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics; -import io.micrometer.binder.logging.LogbackMetrics; +import io.micrometer.core.instrument.binder.logging.LogbackMetrics; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfigurationTests.java index 8b643e49731a..cba6e2c35545 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfigurationTests.java @@ -20,10 +20,10 @@ import java.util.Arrays; import java.util.Collections; -import io.micrometer.binder.system.FileDescriptorMetrics; -import io.micrometer.binder.system.ProcessorMetrics; -import io.micrometer.binder.system.UptimeMetrics; import io.micrometer.core.instrument.Tags; +import io.micrometer.core.instrument.binder.system.FileDescriptorMetrics; +import io.micrometer.core.instrument.binder.system.ProcessorMetrics; +import io.micrometer.core.instrument.binder.system.UptimeMetrics; import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsAutoConfigurationTests.java index 556b53128950..5c16b62c6932 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsAutoConfigurationTests.java @@ -44,8 +44,8 @@ void autoConfiguredCache2kIsInstrumented() { this.contextRunner.withPropertyValues("spring.cache.type=cache2k", "spring.cache.cache-names=cache1,cache2") .run((context) -> { MeterRegistry registry = context.getBean(MeterRegistry.class); - registry.get("cache.gets").tags("name", "cache1").tags("cacheManager", "cacheManager").meter(); - registry.get("cache.gets").tags("name", "cache2").tags("cacheManager", "cacheManager").meter(); + registry.get("cache.gets").tags("name", "cache1").tags("cache.manager", "cacheManager").meter(); + registry.get("cache.gets").tags("name", "cache2").tags("cache.manager", "cacheManager").meter(); }); } @@ -54,8 +54,8 @@ void autoConfiguredCacheManagerIsInstrumented() { this.contextRunner.withPropertyValues("spring.cache.type=caffeine", "spring.cache.cache-names=cache1,cache2") .run((context) -> { MeterRegistry registry = context.getBean(MeterRegistry.class); - registry.get("cache.gets").tags("name", "cache1").tags("cacheManager", "cacheManager").meter(); - registry.get("cache.gets").tags("name", "cache2").tags("cacheManager", "cacheManager").meter(); + registry.get("cache.gets").tags("name", "cache1").tags("cache.manager", "cacheManager").meter(); + registry.get("cache.gets").tags("name", "cache2").tags("cache.manager", "cacheManager").meter(); }); } @@ -64,9 +64,9 @@ void autoConfiguredNonSupportedCacheManagerIsIgnored() { this.contextRunner.withPropertyValues("spring.cache.type=simple", "spring.cache.cache-names=cache1,cache2") .run((context) -> { MeterRegistry registry = context.getBean(MeterRegistry.class); - assertThat(registry.find("cache.gets").tags("name", "cache1").tags("cacheManager", "cacheManager") + assertThat(registry.find("cache.gets").tags("name", "cache1").tags("cache.manager", "cacheManager") .meter()).isNull(); - assertThat(registry.find("cache.gets").tags("name", "cache2").tags("cacheManager", "cacheManager") + assertThat(registry.find("cache.gets").tags("name", "cache2").tags("cache.manager", "cacheManager") .meter()).isNull(); }); } @@ -77,7 +77,7 @@ void cacheInstrumentationCanBeDisabled() { "spring.cache.cache-names=cache1").run((context) -> { MeterRegistry registry = context.getBean(MeterRegistry.class); assertThat(registry.find("cache.requests").tags("name", "cache1") - .tags("cacheManager", "cacheManager").meter()).isNull(); + .tags("cache.manager", "cacheManager").meter()).isNull(); }); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapterTests.java index 003028375421..97117ce9adb5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -125,6 +125,13 @@ void whenPropertiesEnrichWithOneAgentMetadataIsSetAdapterEnrichWithOneAgentMetad assertThat(new DynatracePropertiesConfigAdapter(properties).enrichWithDynatraceMetadata()).isTrue(); } + @Test + void whenPropertiesUseDynatraceInstrumentsIsSetAdapterUseDynatraceInstrumentsReturnsIt() { + DynatraceProperties properties = new DynatraceProperties(); + properties.getV2().setUseDynatraceSummaryInstruments(false); + assertThat(new DynatracePropertiesConfigAdapter(properties).useDynatraceSummaryInstruments()).isFalse(); + } + @Test void whenPropertiesDefaultDimensionsIsSetAdapterDefaultDimensionsReturnsIt() { DynatraceProperties properties = new DynatraceProperties(); @@ -148,6 +155,7 @@ void defaultValues() { assertThat(properties.getV2().getMetricKeyPrefix()).isNull(); assertThat(properties.getV2().isEnrichWithDynatraceMetadata()).isTrue(); assertThat(properties.getV2().getDefaultDimensions()).isNull(); + assertThat(properties.getV2().isUseDynatraceSummaryInstruments()).isTrue(); assertThat(properties.getDeviceId()).isNull(); assertThat(properties.getTechnologyType()).isEqualTo("java"); assertThat(properties.getGroup()).isNull(); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioMetricsExportAutoConfigurationTests.java index d96bcd3508d6..d8af629c2b04 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioMetricsExportAutoConfigurationTests.java @@ -16,8 +16,8 @@ package org.springframework.boot.actuate.autoconfigure.metrics.export.humio; -import io.micrometer.binder.jvm.JvmMemoryMetrics; import io.micrometer.core.instrument.Clock; +import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; import io.micrometer.humio.HumioConfig; import io.micrometer.humio.HumioMeterRegistry; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesConfigAdapterTests.java index 29b2a1ec5ca3..94c604a3f1d9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesConfigAdapterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-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. @@ -51,7 +51,7 @@ void whenPropertiesEnabledIsSetAdapterEnabledReturnsIt() { } @Test - void whenPropertiesBatchSizeIsSetAdapterBatchSizeReturnsIt() { + protected void whenPropertiesBatchSizeIsSetAdapterBatchSizeReturnsIt() { P properties = createProperties(); properties.setBatchSize(10042); assertThat(createConfigAdapter(properties).batchSize()).isEqualTo(10042); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfigurationTests.java index f00a07d514dd..0a300f5b42c8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfigurationTests.java @@ -16,14 +16,12 @@ package org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront; -import java.util.concurrent.LinkedBlockingQueue; - import com.wavefront.sdk.common.WavefrontSender; import io.micrometer.core.instrument.Clock; import io.micrometer.wavefront.WavefrontConfig; import io.micrometer.wavefront.WavefrontMeterRegistry; -import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -31,7 +29,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import static org.assertj.core.api.Assertions.as; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -51,28 +48,22 @@ void backsOffWithoutAClock() { this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(WavefrontMeterRegistry.class)); } - @Test - void failsWithoutAnApiTokenWhenPublishingDirectly() { - this.contextRunner.withUserConfiguration(BaseConfiguration.class) - .run((context) -> assertThat(context).hasFailed()); - } - @Test void autoConfigurationCanBeDisabledWithDefaultsEnabledProperty() { this.contextRunner.withUserConfiguration(BaseConfiguration.class) - .withPropertyValues("management.wavefront.metrics.export.api-token=abcde", + .withPropertyValues("management.wavefront.api-token=abcde", "management.defaults.metrics.export.enabled=false") .run((context) -> assertThat(context).doesNotHaveBean(WavefrontMeterRegistry.class) - .doesNotHaveBean(WavefrontConfig.class).doesNotHaveBean(WavefrontSender.class)); + .doesNotHaveBean(WavefrontConfig.class)); } @Test void autoConfigurationCanBeDisabledWithSpecificEnabledProperty() { this.contextRunner.withUserConfiguration(BaseConfiguration.class) - .withPropertyValues("management.wavefront.metrics.export.api-token=abcde", + .withPropertyValues("management.wavefront.api-token=abcde", "management.wavefront.metrics.export.enabled=false") .run((context) -> assertThat(context).doesNotHaveBean(WavefrontMeterRegistry.class) - .doesNotHaveBean(WavefrontConfig.class).doesNotHaveBean(WavefrontSender.class)); + .doesNotHaveBean(WavefrontConfig.class)); } @Test @@ -83,51 +74,10 @@ void allowsConfigToBeCustomized() { .hasSingleBean(WavefrontSender.class).hasBean("customConfig")); } - @Test - void defaultWavefrontSenderSettingsAreConsistent() { - this.contextRunner.withUserConfiguration(BaseConfiguration.class) - .withPropertyValues("management.wavefront.metrics.export.api-token=abcde").run((context) -> { - WavefrontProperties properties = new WavefrontProperties(); - WavefrontSender sender = context.getBean(WavefrontSender.class); - assertThat(sender) - .extracting("metricsBuffer", as(InstanceOfAssertFactories.type(LinkedBlockingQueue.class))) - .satisfies((queue) -> assertThat(queue.remainingCapacity() + queue.size()) - .isEqualTo(properties.getSender().getMaxQueueSize())); - assertThat(sender).hasFieldOrPropertyWithValue("batchSize", properties.getBatchSize()); - assertThat(sender).hasFieldOrPropertyWithValue("messageSizeBytes", - (int) properties.getSender().getMessageSize().toBytes()); - }); - } - - @Test - void configureWavefrontSender() { - this.contextRunner.withUserConfiguration(BaseConfiguration.class) - .withPropertyValues("management.wavefront.metrics.export.api-token=abcde", - "management.wavefront.metrics.export.batch-size=50", - "management.wavefront.metrics.export.sender.max-queue-size=100", - "management.wavefront.metrics.export.sender.message-size=1KB") - .run((context) -> { - WavefrontSender sender = context.getBean(WavefrontSender.class); - assertThat(sender).hasFieldOrPropertyWithValue("batchSize", 50); - assertThat(sender) - .extracting("metricsBuffer", as(InstanceOfAssertFactories.type(LinkedBlockingQueue.class))) - .satisfies((queue) -> assertThat(queue.remainingCapacity() + queue.size()).isEqualTo(100)); - assertThat(sender).hasFieldOrPropertyWithValue("messageSizeBytes", 1024); - }); - } - - @Test - void allowsWavefrontSenderToBeCustomized() { - this.contextRunner.withUserConfiguration(CustomSenderConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(Clock.class) - .hasSingleBean(WavefrontMeterRegistry.class).hasSingleBean(WavefrontConfig.class) - .hasSingleBean(WavefrontSender.class).hasBean("customSender")); - } - @Test void allowsRegistryToBeCustomized() { this.contextRunner.withUserConfiguration(CustomRegistryConfiguration.class) - .withPropertyValues("management.wavefront.metrics.export.api-token=abcde") + .withPropertyValues("management.wavefront.api-token=abcde") .run((context) -> assertThat(context).hasSingleBean(Clock.class).hasSingleBean(WavefrontConfig.class) .hasSingleBean(WavefrontMeterRegistry.class).hasBean("customRegistry")); } @@ -135,7 +85,7 @@ void allowsRegistryToBeCustomized() { @Test void stopsMeterRegistryWhenContextIsClosed() { this.contextRunner.withUserConfiguration(BaseConfiguration.class) - .withPropertyValues("management.wavefront.metrics.export.api-token=abcde").run((context) -> { + .withPropertyValues("management.wavefront.api-token=abcde").run((context) -> { WavefrontMeterRegistry registry = context.getBean(WavefrontMeterRegistry.class); assertThat(registry.isClosed()).isFalse(); context.close(); @@ -146,6 +96,11 @@ void stopsMeterRegistryWhenContextIsClosed() { @Configuration(proxyBeanMethods = false) static class BaseConfiguration { + @Bean + WavefrontSender customWavefrontSender() { + return Mockito.mock(WavefrontSender.class); + } + @Bean Clock clock() { return Clock.SYSTEM; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapterTests.java index 82a5b6d31d54..145765b78358 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -16,11 +16,11 @@ package org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront; -import java.net.URI; - import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PushRegistryPropertiesConfigAdapterTests; +import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties; +import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties.Metrics.Export; import static org.assertj.core.api.Assertions.assertThat; @@ -28,46 +28,35 @@ * Tests for {@link WavefrontPropertiesConfigAdapter}. * * @author Stephane Nicoll + * @author Moritz Halbritter */ -class WavefrontPropertiesConfigAdapterTests - extends PushRegistryPropertiesConfigAdapterTests { +class WavefrontPropertiesConfigAdapterTests extends + PushRegistryPropertiesConfigAdapterTests { @Override - protected WavefrontProperties createProperties() { - return new WavefrontProperties(); + protected WavefrontProperties.Metrics.Export createProperties() { + return new WavefrontProperties.Metrics.Export(); } @Override - protected WavefrontPropertiesConfigAdapter createConfigAdapter(WavefrontProperties properties) { + protected WavefrontPropertiesConfigAdapter createConfigAdapter(WavefrontProperties.Metrics.Export export) { + WavefrontProperties properties = new WavefrontProperties(); + properties.getMetrics().setExport(export); return new WavefrontPropertiesConfigAdapter(properties); } - @Test - void whenPropertiesUriIsSetAdapterUriReturnsIt() { - WavefrontProperties properties = createProperties(); - properties.setUri(URI.create("https://wavefront.example.com")); - assertThat(createConfigAdapter(properties).uri()).isEqualTo("https://wavefront.example.com"); - } - - @Test - void whenPropertiesSourceIsSetAdapterSourceReturnsIt() { - WavefrontProperties properties = createProperties(); - properties.setSource("test"); - assertThat(createConfigAdapter(properties).source()).isEqualTo("test"); - } - - @Test - void whenPropertiesApiTokenIsSetAdapterApiTokenReturnsIt() { - WavefrontProperties properties = createProperties(); - properties.setApiToken("ABC123"); - assertThat(createConfigAdapter(properties).apiToken()).isEqualTo("ABC123"); - } - @Test void whenPropertiesGlobalPrefixIsSetAdapterGlobalPrefixReturnsIt() { - WavefrontProperties properties = createProperties(); + Export properties = createProperties(); properties.setGlobalPrefix("test"); assertThat(createConfigAdapter(properties).globalPrefix()).isEqualTo("test"); } + @Override + protected void whenPropertiesBatchSizeIsSetAdapterBatchSizeReturnsIt() { + WavefrontProperties properties = new WavefrontProperties(); + properties.getSender().setBatchSize(10042); + assertThat(createConfigAdapter(properties.getMetrics().getExport()).batchSize()).isEqualTo(10042); + } + } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java index 77d37405d325..460232c3bb8a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -29,6 +29,7 @@ import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.boot.LazyInitializationBeanFactoryPostProcessor; import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; @@ -90,6 +91,19 @@ void allDataSourcesCanBeInstrumented() { }); } + @Test + void allDataSourcesCanBeInstrumentedWithLazyInitialization() { + this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)).withInitializer( + (context) -> context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor())) + .withUserConfiguration(TwoDataSourcesConfiguration.class).run((context) -> { + context.getBean("firstDataSource", DataSource.class).getConnection().getMetaData(); + context.getBean("secondOne", DataSource.class).getConnection().getMetaData(); + MeterRegistry registry = context.getBean(MeterRegistry.class); + registry.get("jdbc.connections.max").tags("name", "first").meter(); + registry.get("jdbc.connections.max").tags("name", "secondOne").meter(); + }); + } + @Test void autoConfiguredHikariDataSourceIsInstrumented() { this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) @@ -167,6 +181,21 @@ void someHikariDataSourcesCanBeInstrumented() { }); } + @Test + void allHikariDataSourcesCanBeInstrumentedWhenUsingLazyInitialization() { + this.contextRunner.withUserConfiguration(TwoHikariDataSourcesConfiguration.class) + .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) + .withInitializer((context) -> context + .addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor())) + .run((context) -> { + context.getBean("firstDataSource", DataSource.class).getConnection(); + context.getBean("secondOne", DataSource.class).getConnection(); + MeterRegistry registry = context.getBean(MeterRegistry.class); + registry.get("hikaricp.connections").tags("pool", "firstDataSource").meter(); + registry.get("hikaricp.connections").tags("pool", "secondOne").meter(); + }); + } + @Test void hikariProxiedDataSourceCanBeInstrumented() { this.contextRunner.withUserConfiguration(ProxiedHikariDataSourcesConfiguration.class) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfigurationTests.java index cd323a72ba22..43d96561b7e3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfigurationTests.java @@ -23,12 +23,12 @@ import com.mongodb.client.internal.MongoClientImpl; import com.mongodb.connection.ConnectionPoolSettings; import com.mongodb.event.ConnectionPoolListener; -import io.micrometer.binder.mongodb.DefaultMongoCommandTagsProvider; -import io.micrometer.binder.mongodb.DefaultMongoConnectionPoolTagsProvider; -import io.micrometer.binder.mongodb.MongoCommandTagsProvider; -import io.micrometer.binder.mongodb.MongoConnectionPoolTagsProvider; -import io.micrometer.binder.mongodb.MongoMetricsCommandListener; -import io.micrometer.binder.mongodb.MongoMetricsConnectionPoolListener; +import io.micrometer.core.instrument.binder.mongodb.DefaultMongoCommandTagsProvider; +import io.micrometer.core.instrument.binder.mongodb.DefaultMongoConnectionPoolTagsProvider; +import io.micrometer.core.instrument.binder.mongodb.MongoCommandTagsProvider; +import io.micrometer.core.instrument.binder.mongodb.MongoConnectionPoolTagsProvider; +import io.micrometer.core.instrument.binder.mongodb.MongoMetricsCommandListener; +import io.micrometer.core.instrument.binder.mongodb.MongoMetricsConnectionPoolListener; import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsIntegrationTests.java index d4518ab9f60b..697bb0e086a5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsIntegrationTests.java @@ -22,11 +22,11 @@ import java.util.Set; import java.util.concurrent.CyclicBarrier; -import io.micrometer.binder.jvm.JvmMemoryMetrics; -import io.micrometer.binder.logging.LogbackMetrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.MockClock; import io.micrometer.core.instrument.binder.MeterBinder; +import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; +import io.micrometer.core.instrument.binder.logging.LogbackMetrics; import io.micrometer.core.instrument.simple.SimpleConfig; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import jakarta.servlet.DispatcherType; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfigurationTests.java index 617e5ccb9e4f..1356e9ab5ad9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfigurationTests.java @@ -19,8 +19,8 @@ import java.util.Collections; import java.util.concurrent.atomic.AtomicInteger; -import io.micrometer.binder.tomcat.TomcatMetrics; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.binder.tomcat.TomcatMetrics; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.apache.tomcat.util.modeler.Registry; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfigurationTests.java index fdd38c979636..3b59e4550e8f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfigurationTests.java @@ -19,14 +19,14 @@ import java.util.ArrayList; import java.util.List; -import io.micrometer.common.Tag; -import io.micrometer.common.Tags; +import io.micrometer.common.KeyValue; +import io.micrometer.common.KeyValues; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.observation.MeterObservationHandler; import io.micrometer.core.instrument.search.MeterNotFoundException; import io.micrometer.observation.Observation; import io.micrometer.observation.Observation.Context; -import io.micrometer.observation.Observation.GlobalTagsProvider; +import io.micrometer.observation.Observation.GlobalKeyValuesProvider; import io.micrometer.observation.ObservationHandler; import io.micrometer.observation.ObservationHandler.AllMatchingCompositeObservationHandler; import io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObservationHandler; @@ -104,7 +104,7 @@ void autoConfiguresGlobalTagsProvider() { ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); Context micrometerContext = new Context(); Observation.start("test-observation", micrometerContext, observationRegistry).stop(); - assertThat(micrometerContext.getAllTags()).containsExactly(Tag.of("tag1", "value1")); + assertThat(micrometerContext.getAllKeyValues()).containsExactly(KeyValue.of("tag1", "value1")); }); } @@ -164,16 +164,16 @@ ObservationPredicate customPredicate() { static class GlobalTagsProviders { @Bean - GlobalTagsProvider customTagsProvider() { - return new GlobalTagsProvider<>() { + Observation.GlobalKeyValuesProvider customTagsProvider() { + return new GlobalKeyValuesProvider<>() { @Override public boolean supportsContext(Context context) { return true; } @Override - public Tags getLowCardinalityTags(Context context) { - return Tags.of("tag1", "value1"); + public KeyValues getLowCardinalityKeyValues(Context context) { + return KeyValues.of("tag1", "value1"); } }; } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfigurationTests.java index f3bac5eae322..3c53693c0890 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfigurationTests.java @@ -136,10 +136,10 @@ void backOffIfOAuth2ResourceServerAutoConfigurationPresent() { void backOffIfSaml2RelyingPartyAutoConfigurationPresent() { this.contextRunner.withConfiguration(AutoConfigurations.of(Saml2RelyingPartyAutoConfiguration.class)) .withPropertyValues( - "spring.security.saml2.relyingparty.registration.simplesamlphp.identity-provider.single-sign-on.url=https://simplesaml-for-spring-saml/SSOService.php", - "spring.security.saml2.relyingparty.registration.simplesamlphp.identity-provider.single-sign-on.sign-request=false", - "spring.security.saml2.relyingparty.registration.simplesamlphp.identityprovider.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", - "spring.security.saml2.relyingparty.registration.simplesamlphp.identityprovider.verification.credentials[0].certificate-location=classpath:saml/certificate-location") + "spring.security.saml2.relyingparty.registration.simplesamlphp.asserting-party.single-sign-on.url=https://simplesaml-for-spring-saml/SSOService.php", + "spring.security.saml2.relyingparty.registration.simplesamlphp.asserting-party.single-sign-on.sign-request=false", + "spring.security.saml2.relyingparty.registration.simplesamlphp.asserting-party.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", + "spring.security.saml2.relyingparty.registration.simplesamlphp.asserting-party.verification.credentials[0].certificate-location=classpath:saml/certificate-location") .run((context) -> assertThat(context).doesNotHaveBean(ManagementWebSecurityAutoConfiguration.class) .doesNotHaveBean(MANAGEMENT_SECURITY_FILTER_CHAIN_BEAN)); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfigurationTests.java new file mode 100644 index 000000000000..e0cd2e147053 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfigurationTests.java @@ -0,0 +1,156 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing; + +import brave.Tracer; +import brave.Tracing; +import brave.propagation.CurrentTraceContext; +import brave.propagation.Propagation.Factory; +import brave.sampler.Sampler; +import io.micrometer.tracing.brave.bridge.BraveBaggageManager; +import io.micrometer.tracing.brave.bridge.BraveTracer; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link BraveAutoConfiguration}. + * + * @author Moritz Halbritter + */ +class BraveAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(BraveAutoConfiguration.class)); + + @Test + void shouldSupplyBraveBeans() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(Tracing.class); + assertThat(context).hasSingleBean(Tracer.class); + assertThat(context).hasSingleBean(CurrentTraceContext.class); + assertThat(context).hasSingleBean(Factory.class); + assertThat(context).hasSingleBean(Sampler.class); + }); + } + + @Test + void shouldBackOffOnCustomBraveBeans() { + this.contextRunner.withUserConfiguration(CustomBraveConfiguration.class).run((context) -> { + assertThat(context).hasBean("customTracing"); + assertThat(context).hasSingleBean(Tracing.class); + assertThat(context).hasBean("customTracer"); + assertThat(context).hasSingleBean(Tracer.class); + assertThat(context).hasBean("customCurrentTraceContext"); + assertThat(context).hasSingleBean(CurrentTraceContext.class); + assertThat(context).hasBean("customFactory"); + assertThat(context).hasSingleBean(Factory.class); + assertThat(context).hasBean("customSampler"); + assertThat(context).hasSingleBean(Sampler.class); + }); + } + + @Test + void shouldSupplyMicrometerBeans() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(BraveTracer.class); + assertThat(context).hasSingleBean(BraveBaggageManager.class); + }); + } + + @Test + void shouldBackOffOnCustomMicrometerBraveBeans() { + this.contextRunner.withUserConfiguration(CustomMicrometerBraveConfiguration.class).run((context) -> { + assertThat(context).hasBean("customBraveTracer"); + assertThat(context).hasSingleBean(BraveTracer.class); + assertThat(context).hasBean("customBraveBaggageManager"); + assertThat(context).hasSingleBean(BraveBaggageManager.class); + }); + } + + @Test + void shouldNotSupplyBraveBeansIfBraveIsMissing() { + this.contextRunner.withClassLoader(new FilteredClassLoader("brave")).run((context) -> { + assertThat(context).doesNotHaveBean(Tracing.class); + assertThat(context).doesNotHaveBean(Tracer.class); + assertThat(context).doesNotHaveBean(CurrentTraceContext.class); + assertThat(context).doesNotHaveBean(Factory.class); + assertThat(context).doesNotHaveBean(Sampler.class); + }); + } + + @Test + void shouldNotSupplyMicrometerBeansIfMicrometerIsMissing() { + this.contextRunner.withClassLoader(new FilteredClassLoader("io.micrometer")).run((context) -> { + assertThat(context).doesNotHaveBean(BraveTracer.class); + assertThat(context).doesNotHaveBean(BraveBaggageManager.class); + }); + } + + @Configuration(proxyBeanMethods = false) + private static class CustomBraveConfiguration { + + @Bean + Tracing customTracing() { + return Mockito.mock(Tracing.class); + } + + @Bean + Tracer customTracer() { + return Mockito.mock(Tracer.class); + } + + @Bean + CurrentTraceContext customCurrentTraceContext() { + return Mockito.mock(CurrentTraceContext.class); + } + + @Bean + Factory customFactory() { + return Mockito.mock(Factory.class); + } + + @Bean + Sampler customSampler() { + return Mockito.mock(Sampler.class); + } + + } + + @Configuration(proxyBeanMethods = false) + private static class CustomMicrometerBraveConfiguration { + + @Bean + BraveTracer customBraveTracer() { + return Mockito.mock(BraveTracer.class); + } + + @Bean + BraveBaggageManager customBraveBaggageManager() { + return Mockito.mock(BraveBaggageManager.class); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfigurationTests.java new file mode 100644 index 000000000000..97e602e6bf0c --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfigurationTests.java @@ -0,0 +1,88 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing; + +import io.micrometer.tracing.Tracer; +import io.micrometer.tracing.handler.DefaultTracingObservationHandler; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link MicrometerTracingAutoConfiguration}. + * + * @author Moritz Halbritter + */ +class MicrometerTracingAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(MicrometerTracingAutoConfiguration.class)); + + @Test + void shouldSupplyBeans() { + this.contextRunner.withUserConfiguration(TracerConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(DefaultTracingObservationHandler.class)); + } + + @Test + void shouldBackOffOnCustomBeans() { + this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { + assertThat(context).hasBean("customDefaultTracingObservationHandler"); + assertThat(context).hasSingleBean(DefaultTracingObservationHandler.class); + }); + } + + @Test + void shouldNotSupplyBeansIfMicrometerIsMissing() { + this.contextRunner.withClassLoader(new FilteredClassLoader("io.micrometer")) + .run((context) -> assertThat(context).doesNotHaveBean(DefaultTracingObservationHandler.class)); + } + + @Test + void shouldNotSupplyDefaultTracingObservationHandlerIfTracerIsMissing() { + this.contextRunner + .run((context) -> assertThat(context).doesNotHaveBean(DefaultTracingObservationHandler.class)); + } + + @Configuration(proxyBeanMethods = false) + private static class TracerConfiguration { + + @Bean + Tracer tracer() { + return Mockito.mock(Tracer.class); + } + + } + + @Configuration(proxyBeanMethods = false) + private static class CustomConfiguration { + + @Bean + DefaultTracingObservationHandler customDefaultTracingObservationHandler() { + return Mockito.mock(DefaultTracingObservationHandler.class); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsMicrometerConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsMicrometerConfigurationTests.java new file mode 100644 index 000000000000..6204e462d785 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsMicrometerConfigurationTests.java @@ -0,0 +1,111 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing; + +import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext; +import io.micrometer.tracing.otel.bridge.OtelTracer; +import io.micrometer.tracing.otel.bridge.OtelTracer.EventPublisher; +import io.opentelemetry.api.trace.Tracer; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.MicrometerConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link MicrometerConfiguration}. + * + * @author Moritz Halbritter + */ +class OpenTelemetryConfigurationsMicrometerConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(MicrometerConfiguration.class)); + + @Test + void shouldSupplyBeans() { + this.contextRunner.withUserConfiguration(TracerConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(OtelTracer.class); + assertThat(context).hasSingleBean(EventPublisher.class); + assertThat(context).hasSingleBean(OtelCurrentTraceContext.class); + }); + } + + @Test + void shouldNotSupplyBeansIfMicrometerTracingBridgeOtelIsMissing() { + this.contextRunner.withClassLoader(new FilteredClassLoader("io.micrometer.tracing.otel")) + .withUserConfiguration(TracerConfiguration.class).run((context) -> { + assertThat(context).doesNotHaveBean(OtelTracer.class); + assertThat(context).doesNotHaveBean(EventPublisher.class); + assertThat(context).doesNotHaveBean(OtelCurrentTraceContext.class); + }); + } + + @Test + void shouldNotSupplyOtelTracerIfTracerIsMissing() { + this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(OtelTracer.class)); + } + + @Test + void shouldBackOffOnCustomBeans() { + this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { + assertThat(context).hasBean("customOtelTracer"); + assertThat(context).hasSingleBean(OtelTracer.class); + assertThat(context).hasBean("customEventPublisher"); + assertThat(context).hasSingleBean(EventPublisher.class); + assertThat(context).hasBean("customOtelCurrentTraceContext"); + assertThat(context).hasSingleBean(OtelCurrentTraceContext.class); + }); + } + + @Configuration(proxyBeanMethods = false) + private static class CustomConfiguration { + + @Bean + OtelTracer customOtelTracer() { + return Mockito.mock(OtelTracer.class); + } + + @Bean + EventPublisher customEventPublisher() { + return Mockito.mock(EventPublisher.class); + } + + @Bean + OtelCurrentTraceContext customOtelCurrentTraceContext() { + return Mockito.mock(OtelCurrentTraceContext.class); + } + + } + + @Configuration(proxyBeanMethods = false) + private static class TracerConfiguration { + + @Bean + Tracer tracer() { + return Mockito.mock(Tracer.class); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsSdkConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsSdkConfigurationTests.java new file mode 100644 index 000000000000..6930e77b87f7 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsSdkConfigurationTests.java @@ -0,0 +1,112 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.context.propagation.ContextPropagators; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.SpanProcessor; +import io.opentelemetry.sdk.trace.samplers.Sampler; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.SdkConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SdkConfiguration}. + * + * @author Moritz Halbritter + */ +class OpenTelemetryConfigurationsSdkConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(SdkConfiguration.class)); + + @Test + void shouldSupplyBeans() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(OpenTelemetry.class); + assertThat(context).hasSingleBean(SdkTracerProvider.class); + assertThat(context).hasSingleBean(ContextPropagators.class); + assertThat(context).hasSingleBean(Sampler.class); + assertThat(context).hasSingleBean(SpanProcessor.class); + }); + } + + @Test + void shouldBackOffOnCustomBeans() { + this.contextRunner.withUserConfiguration(CustomBeans.class).run((context) -> { + assertThat(context).hasBean("customOpenTelemetry"); + assertThat(context).hasSingleBean(OpenTelemetry.class); + assertThat(context).hasBean("customSdkTracerProvider"); + assertThat(context).hasSingleBean(SdkTracerProvider.class); + assertThat(context).hasBean("customContextPropagators"); + assertThat(context).hasSingleBean(ContextPropagators.class); + assertThat(context).hasBean("customSampler"); + assertThat(context).hasSingleBean(Sampler.class); + assertThat(context).hasBean("customSpanProcessor"); + assertThat(context).hasSingleBean(SpanProcessor.class); + }); + } + + @Test + void shouldNotSupplyBeansIfSdkIsMissing() { + this.contextRunner.withClassLoader(new FilteredClassLoader("io.opentelemetry.sdk")).run((context) -> { + assertThat(context).doesNotHaveBean(OpenTelemetry.class); + assertThat(context).doesNotHaveBean(SdkTracerProvider.class); + assertThat(context).doesNotHaveBean(ContextPropagators.class); + assertThat(context).doesNotHaveBean(Sampler.class); + assertThat(context).doesNotHaveBean(SpanProcessor.class); + }); + } + + private static class CustomBeans { + + @Bean + OpenTelemetry customOpenTelemetry() { + return Mockito.mock(OpenTelemetry.class); + } + + @Bean + SdkTracerProvider customSdkTracerProvider() { + return SdkTracerProvider.builder().build(); + } + + @Bean + ContextPropagators customContextPropagators() { + return Mockito.mock(ContextPropagators.class); + } + + @Bean + Sampler customSampler() { + return Mockito.mock(Sampler.class); + } + + @Bean + SpanProcessor customSpanProcessor() { + return Mockito.mock(SpanProcessor.class); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsTracerConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsTracerConfigurationTests.java new file mode 100644 index 000000000000..2227eb89d78b --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsTracerConfigurationTests.java @@ -0,0 +1,90 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.trace.Tracer; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.TracerConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link TracerConfiguration}. + * + * @author Moritz Halbritter + */ +class OpenTelemetryConfigurationsTracerConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(TracerConfiguration.class)); + + @Test + void shouldSupplyBeans() { + this.contextRunner.withUserConfiguration(OpenTelemetryConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(Tracer.class)); + } + + @Test + void shouldNotSupplyBeansIfApiIsMissing() { + this.contextRunner.withClassLoader(new FilteredClassLoader("io.opentelemetry.api")) + .run((context) -> assertThat(context).doesNotHaveBean(Tracer.class)); + } + + @Test + void shouldNotSupplyTracerIfOpenTelemetryIsMissing() { + this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(Tracer.class)); + } + + @Test + void shouldBackOffOnCustomBeans() { + this.contextRunner.withUserConfiguration(OpenTelemetryConfiguration.class, CustomConfiguration.class) + .run((context) -> { + assertThat(context).hasBean("customTracer"); + assertThat(context).hasSingleBean(Tracer.class); + }); + + } + + @Configuration(proxyBeanMethods = false) + private static class OpenTelemetryConfiguration { + + @Bean + OpenTelemetry tracer() { + return Mockito.mock(OpenTelemetry.class); + } + + } + + @Configuration(proxyBeanMethods = false) + private static class CustomConfiguration { + + @Bean + Tracer customTracer() { + return Mockito.mock(Tracer.class); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/MeterRegistrySpanMetricsTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/MeterRegistrySpanMetricsTests.java new file mode 100644 index 000000000000..cf0f3b575ac2 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/MeterRegistrySpanMetricsTests.java @@ -0,0 +1,101 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing.wavefront; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.Gauge; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link MeterRegistrySpanMetrics}. + * + * @author Moritz Halbritter + */ +class MeterRegistrySpanMetricsTests { + + private SimpleMeterRegistry meterRegistry; + + private MeterRegistrySpanMetrics sut; + + @BeforeEach + void setUp() { + this.meterRegistry = new SimpleMeterRegistry(); + this.sut = new MeterRegistrySpanMetrics(this.meterRegistry); + } + + @Test + void reportDroppedShouldIncreaseCounter() { + this.sut.reportDropped(); + assertThat(getCounterValue("wavefront.reporter.spans.dropped")).isEqualTo(1); + this.sut.reportDropped(); + assertThat(getCounterValue("wavefront.reporter.spans.dropped")).isEqualTo(2); + } + + @Test + void reportReceivedShouldIncreaseCounter() { + this.sut.reportReceived(); + assertThat(getCounterValue("wavefront.reporter.spans.received")).isEqualTo(1); + this.sut.reportReceived(); + assertThat(getCounterValue("wavefront.reporter.spans.received")).isEqualTo(2); + } + + @Test + void reportErrorsShouldIncreaseCounter() { + this.sut.reportErrors(); + assertThat(getCounterValue("wavefront.reporter.errors")).isEqualTo(1); + this.sut.reportErrors(); + assertThat(getCounterValue("wavefront.reporter.errors")).isEqualTo(2); + } + + @Test + void registerQueueSizeShouldCreateGauge() { + BlockingQueue queue = new ArrayBlockingQueue(2); + this.sut.registerQueueSize(queue); + assertThat(getGaugeValue("wavefront.reporter.queue.size")).isEqualTo(0); + queue.offer(1); + assertThat(getGaugeValue("wavefront.reporter.queue.size")).isEqualTo(1); + } + + @Test + void registerQueueRemainingCapacityShouldCreateGauge() { + BlockingQueue queue = new ArrayBlockingQueue(2); + this.sut.registerQueueRemainingCapacity(queue); + assertThat(getGaugeValue("wavefront.reporter.queue.remaining_capacity")).isEqualTo(2); + queue.offer(1); + assertThat(getGaugeValue("wavefront.reporter.queue.remaining_capacity")).isEqualTo(1); + } + + private double getGaugeValue(String name) { + Gauge gauge = this.meterRegistry.find(name).gauge(); + assertThat(gauge).withFailMessage("Gauge '%s' not found", name).isNotNull(); + return gauge.value(); + } + + private double getCounterValue(String name) { + Counter counter = this.meterRegistry.find(name).counter(); + assertThat(counter).withFailMessage("Counter '%s' not found", name).isNotNull(); + return counter.count(); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfigurationTests.java new file mode 100644 index 000000000000..5479337330b9 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfigurationTests.java @@ -0,0 +1,192 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing.wavefront; + +import com.wavefront.sdk.common.WavefrontSender; +import com.wavefront.sdk.common.application.ApplicationTags; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import io.micrometer.tracing.reporter.wavefront.SpanMetrics; +import io.micrometer.tracing.reporter.wavefront.WavefrontBraveSpanHandler; +import io.micrometer.tracing.reporter.wavefront.WavefrontOtelSpanHandler; +import io.micrometer.tracing.reporter.wavefront.WavefrontSpanHandler; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link WavefrontTracingAutoConfiguration}. + * + * @author Moritz Halbritter + */ +class WavefrontTracingAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(WavefrontTracingAutoConfiguration.class)); + + @Test + void shouldSupplyBeans() { + this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(ApplicationTags.class); + assertThat(context).hasSingleBean(WavefrontSpanHandler.class); + assertThat(context).hasSingleBean(SpanMetrics.class); + assertThat(context).hasSingleBean(WavefrontBraveSpanHandler.class); + assertThat(context).hasSingleBean(WavefrontOtelSpanHandler.class); + }); + } + + @Test + void shouldNotSupplyBeansIfWavefrontSenderIsMissing() { + this.contextRunner.run((context) -> { + assertThat(context).doesNotHaveBean(ApplicationTags.class); + assertThat(context).doesNotHaveBean(WavefrontSpanHandler.class); + assertThat(context).doesNotHaveBean(SpanMetrics.class); + assertThat(context).doesNotHaveBean(WavefrontBraveSpanHandler.class); + assertThat(context).doesNotHaveBean(WavefrontOtelSpanHandler.class); + }); + } + + @Test + void shouldNotSupplyBeansIfMicrometerReporterWavefrontIsMissing() { + this.contextRunner.withClassLoader(new FilteredClassLoader("io.micrometer.tracing.reporter.wavefront")) + .withUserConfiguration(WavefrontSenderConfiguration.class).run((context) -> { + assertThat(context).doesNotHaveBean(WavefrontSpanHandler.class); + assertThat(context).doesNotHaveBean(SpanMetrics.class); + assertThat(context).doesNotHaveBean(WavefrontBraveSpanHandler.class); + assertThat(context).doesNotHaveBean(WavefrontOtelSpanHandler.class); + }); + } + + @Test + void shouldSupplyMeterRegistrySpanMetricsIfMeterRegistryIsAvailable() { + this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class, MeterRegistryConfiguration.class) + .run((context) -> { + assertThat(context).hasSingleBean(SpanMetrics.class); + assertThat(context).hasSingleBean(MeterRegistrySpanMetrics.class); + }); + } + + @Test + void shouldNotSupplyWavefrontBraveSpanHandlerIfBraveIsMissing() { + this.contextRunner.withClassLoader(new FilteredClassLoader("brave")) + .withUserConfiguration(WavefrontSenderConfiguration.class) + .run((context) -> assertThat(context).doesNotHaveBean(WavefrontBraveSpanHandler.class)); + } + + @Test + void shouldNotSupplyWavefrontOtelSpanHandlerIfOtelIsMissing() { + this.contextRunner.withClassLoader(new FilteredClassLoader("io.opentelemetry.sdk.trace")) + .withUserConfiguration(WavefrontSenderConfiguration.class) + .run((context) -> assertThat(context).doesNotHaveBean(WavefrontOtelSpanHandler.class)); + } + + @Test + void shouldHaveADefaultApplicationName() { + this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class).run((context) -> { + ApplicationTags applicationTags = context.getBean(ApplicationTags.class); + assertThat(applicationTags.getApplication()).isEqualTo("application"); + }); + } + + @Test + void shouldHonorConfigProperties() { + this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class) + .withPropertyValues("spring.application.name=super-application", + "management.wavefront.tracing.service-name=super-service") + .run((context) -> { + ApplicationTags applicationTags = context.getBean(ApplicationTags.class); + assertThat(applicationTags.getApplication()).isEqualTo("super-application"); + assertThat(applicationTags.getService()).isEqualTo("super-service"); + }); + } + + @Test + void shouldBackOffOnCustomBeans() { + this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class, CustomConfiguration.class) + .run((context) -> { + assertThat(context).hasBean("customApplicationTags"); + assertThat(context).hasSingleBean(ApplicationTags.class); + assertThat(context).hasBean("customWavefrontSpanHandler"); + assertThat(context).hasSingleBean(WavefrontSpanHandler.class); + assertThat(context).hasBean("customSpanMetrics"); + assertThat(context).hasSingleBean(SpanMetrics.class); + assertThat(context).hasBean("customWavefrontBraveSpanHandler"); + assertThat(context).hasSingleBean(WavefrontBraveSpanHandler.class); + assertThat(context).hasBean("customWavefrontOtelSpanHandler"); + assertThat(context).hasSingleBean(WavefrontOtelSpanHandler.class); + }); + } + + @Configuration(proxyBeanMethods = false) + private static class CustomConfiguration { + + @Bean + ApplicationTags customApplicationTags() { + return Mockito.mock(ApplicationTags.class); + } + + @Bean + WavefrontSpanHandler customWavefrontSpanHandler() { + return Mockito.mock(WavefrontSpanHandler.class); + } + + @Bean + SpanMetrics customSpanMetrics() { + return Mockito.mock(SpanMetrics.class); + } + + @Bean + WavefrontBraveSpanHandler customWavefrontBraveSpanHandler() { + return Mockito.mock(WavefrontBraveSpanHandler.class); + } + + @Bean + WavefrontOtelSpanHandler customWavefrontOtelSpanHandler() { + return Mockito.mock(WavefrontOtelSpanHandler.class); + } + + } + + @Configuration(proxyBeanMethods = false) + private static class WavefrontSenderConfiguration { + + @Bean + WavefrontSender wavefrontSender() { + return mock(WavefrontSender.class); + } + + } + + @Configuration(proxyBeanMethods = false) + private static class MeterRegistryConfiguration { + + @Bean + MeterRegistry meterRegistry() { + return new SimpleMeterRegistry(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/NoopSender.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/NoopSender.java new file mode 100644 index 000000000000..48a7926e7818 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/NoopSender.java @@ -0,0 +1,62 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; + +import java.util.List; + +import zipkin2.Call; +import zipkin2.Callback; +import zipkin2.codec.Encoding; +import zipkin2.reporter.Sender; + +class NoopSender extends Sender { + + @Override + public Encoding encoding() { + return Encoding.JSON; + } + + @Override + public int messageMaxBytes() { + return 1024; + } + + @Override + public int messageSizeInBytes(List encodedSpans) { + return encoding().listSizeInBytes(encodedSpans); + } + + @Override + public Call sendSpans(List encodedSpans) { + return new Call.Base<>() { + @Override + public Call clone() { + return this; + } + + @Override + protected Void doExecute() { + return null; + } + + @Override + protected void doEnqueue(Callback callback) { + } + }; + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfigurationTests.java new file mode 100644 index 000000000000..4b15fdda923f --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfigurationTests.java @@ -0,0 +1,71 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; + +import org.junit.jupiter.api.Test; +import zipkin2.Span; +import zipkin2.codec.BytesEncoder; +import zipkin2.codec.SpanBytesEncoder; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ZipkinAutoConfiguration}. + * + * @author Moritz Halbritter + */ +class ZipkinAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ZipkinAutoConfiguration.class)); + + @Test + void shouldSupplyBeans() { + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(BytesEncoder.class)); + } + + @Test + void shouldNotSupplyBeansIfZipkinReporterIsMissing() { + this.contextRunner.withClassLoader(new FilteredClassLoader("zipkin2.reporter")) + .run((context) -> assertThat(context).doesNotHaveBean(BytesEncoder.class)); + } + + @Test + void shouldBackOffOnCustomBeans() { + this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { + assertThat(context).hasBean("customBytesEncoder"); + assertThat(context).hasSingleBean(BytesEncoder.class); + }); + } + + @Configuration(proxyBeanMethods = false) + private static class CustomConfiguration { + + @Bean + BytesEncoder customBytesEncoder() { + return SpanBytesEncoder.JSON_V2; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsBraveConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsBraveConfigurationTests.java new file mode 100644 index 000000000000..2ac0c6f56559 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsBraveConfigurationTests.java @@ -0,0 +1,92 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; + +import brave.handler.SpanHandler; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import zipkin2.Span; +import zipkin2.reporter.Reporter; + +import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.BraveConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link BraveConfiguration}. + * + * @author Moritz Halbritter + */ +class ZipkinConfigurationsBraveConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(BraveConfiguration.class)); + + @Test + void shouldSupplyBeans() { + this.contextRunner.withUserConfiguration(ReporterConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(SpanHandler.class)); + } + + @Test + void shouldNotSupplySpanHandlerIfReporterIsMissing() { + this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(SpanHandler.class)); + } + + @Test + void shouldNotSupplyIfZipkinReporterBraveIsNotOnClasspath() { + this.contextRunner.withClassLoader(new FilteredClassLoader("zipkin2.reporter.brave")) + .withUserConfiguration(ReporterConfiguration.class) + .run((context) -> assertThat(context).doesNotHaveBean(SpanHandler.class)); + + } + + @Test + void shouldBackOffOnCustomBeans() { + this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { + assertThat(context).hasBean("customSpanHandler"); + assertThat(context).hasSingleBean(SpanHandler.class); + }); + } + + @Configuration(proxyBeanMethods = false) + private static class ReporterConfiguration { + + @Bean + @SuppressWarnings("unchecked") + Reporter reporter() { + return Mockito.mock(Reporter.class); + } + + } + + @Configuration(proxyBeanMethods = false) + private static class CustomConfiguration { + + @Bean + SpanHandler customSpanHandler() { + return Mockito.mock(SpanHandler.class); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java new file mode 100644 index 000000000000..14ba3e413d20 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java @@ -0,0 +1,104 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; + +import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; +import org.junit.jupiter.api.Test; +import zipkin2.Span; +import zipkin2.codec.BytesEncoder; +import zipkin2.codec.SpanBytesEncoder; +import zipkin2.reporter.Sender; + +import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.OpenTelemetryConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link OpenTelemetryConfiguration}. + * + * @author Moritz Halbritter + */ +class ZipkinConfigurationsOpenTelemetryConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(BaseConfiguration.class, OpenTelemetryConfiguration.class)); + + @Test + void shouldSupplyBeans() { + this.contextRunner.withUserConfiguration(SenderConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(ZipkinSpanExporter.class)); + } + + @Test + void shouldNotSupplyZipkinSpanExporterIfSenderIsMissing() { + this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(ZipkinSpanExporter.class)); + } + + @Test + void shouldNotSupplyZipkinSpanExporterIfNotOnClasspath() { + this.contextRunner.withClassLoader(new FilteredClassLoader("io.opentelemetry.exporter.zipkin")) + .withUserConfiguration(SenderConfiguration.class) + .run((context) -> assertThat(context).doesNotHaveBean(ZipkinSpanExporter.class)); + + } + + @Test + void shouldBackOffOnCustomBeans() { + this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { + assertThat(context).hasBean("customZipkinSpanExporter"); + assertThat(context).hasSingleBean(ZipkinSpanExporter.class); + }); + } + + @Configuration(proxyBeanMethods = false) + private static class SenderConfiguration { + + @Bean + Sender sender() { + return new NoopSender(); + } + + } + + @Configuration(proxyBeanMethods = false) + private static class CustomConfiguration { + + @Bean + ZipkinSpanExporter customZipkinSpanExporter() { + return ZipkinSpanExporter.builder().build(); + } + + } + + @Configuration(proxyBeanMethods = false) + private static class BaseConfiguration { + + @Bean + @ConditionalOnMissingBean + BytesEncoder spanBytesEncoder() { + return SpanBytesEncoder.JSON_V2; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsReporterConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsReporterConfigurationTests.java new file mode 100644 index 000000000000..e5d115927d18 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsReporterConfigurationTests.java @@ -0,0 +1,97 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; + +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import zipkin2.Span; +import zipkin2.codec.BytesEncoder; +import zipkin2.codec.SpanBytesEncoder; +import zipkin2.reporter.Reporter; +import zipkin2.reporter.Sender; + +import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.ReporterConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ReporterConfiguration}. + * + * @author Moritz Halbritter + */ +class ZipkinConfigurationsReporterConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(BaseConfiguration.class, ReporterConfiguration.class)); + + @Test + void shouldSupplyBeans() { + this.contextRunner.withUserConfiguration(SenderConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(Reporter.class)); + } + + @Test + void shouldNotSupplyReporterIfSenderIsMissing() { + this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(Reporter.class)); + } + + @Test + void shouldBackOffOnCustomBeans() { + this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { + assertThat(context).hasBean("customReporter"); + assertThat(context).hasSingleBean(Reporter.class); + }); + } + + @Configuration(proxyBeanMethods = false) + private static class SenderConfiguration { + + @Bean + Sender sender() { + return new NoopSender(); + } + + } + + @Configuration(proxyBeanMethods = false) + private static class CustomConfiguration { + + @Bean + @SuppressWarnings("unchecked") + Reporter customReporter() { + return Mockito.mock(Reporter.class); + } + + } + + @Configuration(proxyBeanMethods = false) + private static class BaseConfiguration { + + @Bean + @ConditionalOnMissingBean + BytesEncoder spanBytesEncoder() { + return SpanBytesEncoder.JSON_V2; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsSenderConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsSenderConfigurationTests.java new file mode 100644 index 000000000000..48a697e5c38e --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsSenderConfigurationTests.java @@ -0,0 +1,100 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; + +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import zipkin2.reporter.Sender; +import zipkin2.reporter.urlconnection.URLConnectionSender; + +import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.SenderConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SenderConfiguration}. + * + * @author Moritz Halbritter + */ +class ZipkinConfigurationsSenderConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(SenderConfiguration.class)); + + @Test + void shouldSupplyBeans() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(Sender.class); + assertThat(context).hasSingleBean(URLConnectionSender.class); + assertThat(context).doesNotHaveBean(ZipkinRestTemplateSender.class); + }); + } + + @Test + void shouldUseRestTemplateSenderIfUrlConnectionSenderIsNotAvailable() { + this.contextRunner.withUserConfiguration(RestTemplateConfiguration.class) + .withClassLoader(new FilteredClassLoader("zipkin2.reporter.urlconnection")).run((context) -> { + assertThat(context).doesNotHaveBean(URLConnectionSender.class); + assertThat(context).hasSingleBean(Sender.class); + assertThat(context).hasSingleBean(ZipkinRestTemplateSender.class); + }); + } + + @Test + void shouldNotSupplyRestTemplateSenderIfNoBuilderIsAvailable() { + this.contextRunner.run((context) -> { + assertThat(context).doesNotHaveBean(ZipkinRestTemplateSender.class); + assertThat(context).hasSingleBean(Sender.class); + assertThat(context).hasSingleBean(URLConnectionSender.class); + }); + } + + @Test + void shouldBackOffOnCustomBeans() { + this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { + assertThat(context).hasBean("customSender"); + assertThat(context).hasSingleBean(Sender.class); + }); + } + + @Configuration(proxyBeanMethods = false) + private static class RestTemplateConfiguration { + + @Bean + RestTemplateBuilder restTemplateBuilder() { + return new RestTemplateBuilder(); + } + + } + + @Configuration(proxyBeanMethods = false) + private static class CustomConfiguration { + + @Bean + Sender customSender() { + return Mockito.mock(Sender.class); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSenderTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSenderTests.java new file mode 100644 index 000000000000..526d45be7df8 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSenderTests.java @@ -0,0 +1,122 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.List; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import zipkin2.CheckResult; +import zipkin2.reporter.ClosedSenderException; + +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.web.client.RestTemplate; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.content; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.header; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; + +/** + * Tests for {@link ZipkinRestTemplateSender}. + * + * @author Moritz Halbritter + */ +class ZipkinRestTemplateSenderTests { + + private static final String ZIPKIN_URL = "http://localhost:9411/api/v2/spans"; + + private MockRestServiceServer mockServer; + + private ZipkinRestTemplateSender sut; + + @BeforeEach + void setUp() { + RestTemplate restTemplate = new RestTemplate(); + this.mockServer = MockRestServiceServer.createServer(restTemplate); + this.sut = new ZipkinRestTemplateSender(ZIPKIN_URL, restTemplate); + } + + @AfterEach + void tearDown() { + this.mockServer.verify(); + } + + @Test + void checkShouldSendEmptySpanList() { + this.mockServer.expect(requestTo(ZIPKIN_URL)).andExpect(method(HttpMethod.POST)) + .andExpect(content().string("[]")).andRespond(withStatus(HttpStatus.ACCEPTED)); + assertThat(this.sut.check()).isEqualTo(CheckResult.OK); + } + + @Test + void checkShouldNotRaiseException() { + this.mockServer.expect(requestTo(ZIPKIN_URL)).andExpect(method(HttpMethod.POST)) + .andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR)); + CheckResult result = this.sut.check(); + assertThat(result.ok()).isFalse(); + assertThat(result.error()).hasMessageContaining("500 Internal Server Error"); + } + + @Test + void sendSpansShouldSendSpansToZipkin() throws IOException { + this.mockServer.expect(requestTo(ZIPKIN_URL)).andExpect(method(HttpMethod.POST)) + .andExpect(content().contentType("application/json")).andExpect(content().string("[span1,span2]")) + .andRespond(withStatus(HttpStatus.ACCEPTED)); + this.sut.sendSpans(List.of(toByteArray("span1"), toByteArray("span2"))).execute(); + } + + @Test + void sendSpansShouldThrowOnHttpFailure() throws IOException { + this.mockServer.expect(requestTo(ZIPKIN_URL)).andExpect(method(HttpMethod.POST)) + .andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR)); + assertThatThrownBy(() -> this.sut.sendSpans(List.of()).execute()) + .hasMessageContaining("500 Internal Server Error"); + } + + @Test + void sendSpansShouldThrowIfCloseWasCalled() throws IOException { + this.sut.close(); + assertThatThrownBy(() -> this.sut.sendSpans(List.of())).isInstanceOf(ClosedSenderException.class); + } + + @Test + void sendSpansShouldCompressData() throws IOException { + String uncompressed = "a".repeat(10000); + // This is gzip compressed 10000 times 'a' + byte[] compressed = Base64.getDecoder() + .decode("H4sIAAAAAAAA/+3BMQ0AAAwDIKFLj/k3UR8NcA8AAAAAAAAAAAADUsAZfeASJwAA"); + this.mockServer.expect(requestTo(ZIPKIN_URL)).andExpect(method(HttpMethod.POST)) + .andExpect(header("Content-Encoding", "gzip")).andExpect(content().contentType("application/json")) + .andExpect(content().bytes(compressed)).andRespond(withStatus(HttpStatus.ACCEPTED)); + this.sut.sendSpans(List.of(toByteArray(uncompressed))).execute(); + } + + private byte[] toByteArray(String input) { + return input.getBytes(StandardCharsets.UTF_8); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfigurationTests.java new file mode 100644 index 000000000000..2f20023e8f13 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfigurationTests.java @@ -0,0 +1,101 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.wavefront; + +import java.util.concurrent.LinkedBlockingQueue; + +import com.wavefront.sdk.common.WavefrontSender; +import org.assertj.core.api.InstanceOfAssertFactories; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.as; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link WavefrontAutoConfiguration}. + * + * @author Moritz Halbritter + */ +class WavefrontAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(WavefrontAutoConfiguration.class)); + + @Test + void shouldNotFailIfWavefrontIsMissing() { + this.contextRunner.withClassLoader(new FilteredClassLoader("com.wavefront")) + .run(((context) -> assertThat(context).doesNotHaveBean(WavefrontSender.class))); + } + + @Test + void failsWithoutAnApiTokenWhenPublishingDirectly() { + this.contextRunner.run((context) -> assertThat(context).hasFailed()); + } + + @Test + void defaultWavefrontSenderSettingsAreConsistent() { + this.contextRunner.withPropertyValues("management.wavefront.api-token=abcde").run((context) -> { + WavefrontProperties properties = new WavefrontProperties(); + WavefrontSender sender = context.getBean(WavefrontSender.class); + assertThat(sender) + .extracting("metricsBuffer", as(InstanceOfAssertFactories.type(LinkedBlockingQueue.class))) + .satisfies((queue) -> assertThat(queue.remainingCapacity() + queue.size()) + .isEqualTo(properties.getSender().getMaxQueueSize())); + assertThat(sender).hasFieldOrPropertyWithValue("batchSize", properties.getSender().getBatchSize()); + assertThat(sender).hasFieldOrPropertyWithValue("messageSizeBytes", + (int) properties.getSender().getMessageSize().toBytes()); + }); + } + + @Test + void configureWavefrontSender() { + this.contextRunner.withPropertyValues("management.wavefront.api-token=abcde", + "management.wavefront.sender.batch-size=50", "management.wavefront.sender.max-queue-size=100", + "management.wavefront.sender.message-size=1KB").run((context) -> { + WavefrontSender sender = context.getBean(WavefrontSender.class); + assertThat(sender).hasFieldOrPropertyWithValue("batchSize", 50); + assertThat(sender) + .extracting("metricsBuffer", as(InstanceOfAssertFactories.type(LinkedBlockingQueue.class))) + .satisfies((queue) -> assertThat(queue.remainingCapacity() + queue.size()).isEqualTo(100)); + assertThat(sender).hasFieldOrPropertyWithValue("messageSizeBytes", 1024); + }); + } + + @Test + void allowsWavefrontSenderToBeCustomized() { + this.contextRunner.withUserConfiguration(CustomSenderConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(WavefrontSender.class).hasBean("customSender")); + } + + @Configuration(proxyBeanMethods = false) + static class CustomSenderConfiguration { + + @Bean + WavefrontSender customSender() { + return mock(WavefrontSender.class); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontPropertiesMetricsExportTests.java similarity index 58% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesTests.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontPropertiesMetricsExportTests.java index 4ec6050d468c..f467aa7c374a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontPropertiesMetricsExportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-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. @@ -14,29 +14,31 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront; +package org.springframework.boot.actuate.autoconfigure.wavefront; import io.micrometer.wavefront.WavefrontConfig; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PushRegistryPropertiesTests; - import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link WavefrontProperties}. + * Tests for {@link WavefrontProperties.Metrics.Export}. * * @author Stephane Nicoll + * @author Moritz Halbritter */ -class WavefrontPropertiesTests extends PushRegistryPropertiesTests { +class WavefrontPropertiesMetricsExportTests { @Test + @SuppressWarnings("deprecation") void defaultValuesAreConsistent() { - WavefrontProperties properties = new WavefrontProperties(); + WavefrontProperties.Metrics.Export properties = new WavefrontProperties.Metrics.Export(); WavefrontConfig config = WavefrontConfig.DEFAULT_DIRECT; - assertStepRegistryDefaultValues(properties, config); - assertThat(properties.getUri().toString()).isEqualTo(config.uri()); + assertThat(properties.getConnectTimeout()).isEqualTo(config.connectTimeout()); assertThat(properties.getGlobalPrefix()).isEqualTo(config.globalPrefix()); + assertThat(properties.getReadTimeout()).isEqualTo(config.readTimeout()); + assertThat(properties.getStep()).isEqualTo(config.step()); + assertThat(properties.isEnabled()).isEqualTo(config.enabled()); } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontPropertiesTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontPropertiesTests.java new file mode 100644 index 000000000000..b5bcbd1e21ec --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontPropertiesTests.java @@ -0,0 +1,54 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.wavefront; + +import java.net.URI; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * Tests for {@link WavefrontProperties}. + * + * @author Moritz Halbritter + */ +class WavefrontPropertiesTests { + + @Test + void apiTokenIsOptionalWhenUsingProxy() { + WavefrontProperties sut = new WavefrontProperties(); + sut.setUri(URI.create("proxy://localhost:2878")); + sut.setApiToken(null); + assertThat(sut.getApiTokenOrThrow()).isNull(); + assertThat(sut.getEffectiveUri()).isEqualTo(URI.create("http://localhost:2878")); + } + + @Test + void apiTokenIsMandatoryWhenNotUsingProxy() { + WavefrontProperties sut = new WavefrontProperties(); + sut.setUri(URI.create("http://localhost:2878")); + sut.setApiToken(null); + assertThat(sut.getEffectiveUri()).isEqualTo(URI.create("http://localhost:2878")); + assertThatThrownBy(sut::getApiTokenOrThrow).isInstanceOf(InvalidConfigurationPropertyValueException.class) + .hasMessageContaining("management.wavefront.api-token"); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/build.gradle b/spring-boot-project/spring-boot-actuator/build.gradle index 15af104f6a46..2a9613bb600e 100644 --- a/spring-boot-project/spring-boot-actuator/build.gradle +++ b/spring-boot-project/spring-boot-actuator/build.gradle @@ -24,7 +24,6 @@ dependencies { optional("io.lettuce:lettuce-core") optional("io.micrometer:micrometer-observation") optional("io.micrometer:micrometer-core") - optional("io.micrometer:micrometer-binders") optional("io.micrometer:micrometer-tracing-api") optional("io.micrometer:micrometer-registry-prometheus") optional("io.prometheus:simpleclient_pushgateway") { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicator.java index 37c5601fcfd8..caf297370925 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicator.java @@ -26,6 +26,8 @@ import org.springframework.boot.actuate.health.Status; import org.springframework.core.ParameterizedTypeReference; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; +import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.WebClient; @@ -62,12 +64,16 @@ private Mono getHealth(Health.Builder builder, WebClient webClient) { } private Mono doHealthCheck(Health.Builder builder, ClientResponse response) { - if (response.statusCode().is2xxSuccessful()) { + HttpStatusCode httpStatusCode = response.statusCode(); + HttpStatus httpStatus = HttpStatus.resolve(httpStatusCode.value()); + if (httpStatusCode.is2xxSuccessful()) { return response.bodyToMono(STRING_OBJECT_MAP).map((body) -> getHealth(builder, body)); } builder.down(); - builder.withDetail("statusCode", response.rawStatusCode()); - builder.withDetail("reasonPhrase", response.statusCode().getReasonPhrase()); + builder.withDetail("statusCode", httpStatusCode.value()); + if (httpStatus != null) { + builder.withDetail("reasonPhrase", httpStatus.getReasonPhrase()); + } return response.releaseBody().thenReturn(builder.build()); } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicator.java new file mode 100644 index 000000000000..ad1d44f2e38f --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicator.java @@ -0,0 +1,85 @@ +/* + * Copyright 2012-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.boot.actuate.elasticsearch; + +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +import org.apache.http.HttpStatus; +import org.apache.http.StatusLine; +import org.elasticsearch.client.Request; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; + +import org.springframework.boot.actuate.health.AbstractHealthIndicator; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.json.JsonParser; +import org.springframework.boot.json.JsonParserFactory; +import org.springframework.util.StreamUtils; + +/** + * {@link HealthIndicator} for an Elasticsearch cluster using a {@link RestClient}. + * + * @author Artsiom Yudovin + * @author Brian Clozel + * @author Filip Hrisafov + * @since 2.7.0 + */ +public class ElasticsearchRestClientHealthIndicator extends AbstractHealthIndicator { + + private static final String RED_STATUS = "red"; + + private final RestClient client; + + private final JsonParser jsonParser; + + public ElasticsearchRestClientHealthIndicator(RestClient client) { + super("Elasticsearch health check failed"); + this.client = client; + this.jsonParser = JsonParserFactory.getJsonParser(); + } + + @Override + protected void doHealthCheck(Health.Builder builder) throws Exception { + Response response = this.client.performRequest(new Request("GET", "/_cluster/health/")); + StatusLine statusLine = response.getStatusLine(); + if (statusLine.getStatusCode() != HttpStatus.SC_OK) { + builder.down(); + builder.withDetail("statusCode", statusLine.getStatusCode()); + builder.withDetail("reasonPhrase", statusLine.getReasonPhrase()); + return; + } + try (InputStream inputStream = response.getEntity().getContent()) { + doHealthCheck(builder, StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8)); + } + } + + private void doHealthCheck(Health.Builder builder, String json) { + Map response = this.jsonParser.parseMap(json); + String status = (String) response.get("status"); + if (RED_STATUS.equals(status)) { + builder.outOfService(); + } + else { + builder.up(); + } + builder.withDetails(response); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java index 468f235c3b18..1e9f78e8e632 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java @@ -16,22 +16,9 @@ package org.springframework.boot.actuate.elasticsearch; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.Map; - -import org.apache.http.HttpStatus; -import org.apache.http.StatusLine; -import org.elasticsearch.client.Request; -import org.elasticsearch.client.Response; import org.elasticsearch.client.RestClient; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.json.JsonParser; -import org.springframework.boot.json.JsonParserFactory; -import org.springframework.util.StreamUtils; /** * {@link HealthIndicator} for an Elasticsearch cluster using a {@link RestClient}. @@ -40,51 +27,18 @@ * @author Brian Clozel * @author Filip Hrisafov * @since 2.1.1 + * @deprecated since 2.7.0 for removal in 2.9.0 in favor of + * {@link ElasticsearchRestClientHealthIndicator} */ -public class ElasticsearchRestHealthIndicator extends AbstractHealthIndicator { - - private static final String RED_STATUS = "red"; - - private final RestClient client; - - private final JsonParser jsonParser; +@Deprecated +public class ElasticsearchRestHealthIndicator extends ElasticsearchRestClientHealthIndicator { - @SuppressWarnings("deprecation") public ElasticsearchRestHealthIndicator(org.elasticsearch.client.RestHighLevelClient client) { this(client.getLowLevelClient()); } public ElasticsearchRestHealthIndicator(RestClient client) { - super("Elasticsearch health check failed"); - this.client = client; - this.jsonParser = JsonParserFactory.getJsonParser(); - } - - @Override - protected void doHealthCheck(Health.Builder builder) throws Exception { - Response response = this.client.performRequest(new Request("GET", "/_cluster/health/")); - StatusLine statusLine = response.getStatusLine(); - if (statusLine.getStatusCode() != HttpStatus.SC_OK) { - builder.down(); - builder.withDetail("statusCode", statusLine.getStatusCode()); - builder.withDetail("reasonPhrase", statusLine.getReasonPhrase()); - return; - } - try (InputStream inputStream = response.getEntity().getContent()) { - doHealthCheck(builder, StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8)); - } - } - - private void doHealthCheck(Health.Builder builder, String json) { - Map response = this.jsonParser.parseMap(json); - String status = (String) response.get("status"); - if (RED_STATUS.equals(status)) { - builder.outOfService(); - } - else { - builder.up(); - } - builder.withDetails(response); + super(client); } } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProvider.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProvider.java index 71eb38bc42d2..120bb2a06a66 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProvider.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProvider.java @@ -16,9 +16,9 @@ package org.springframework.boot.actuate.metrics.cache; -import io.micrometer.binder.cache.CaffeineCacheMetrics; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.binder.MeterBinder; +import io.micrometer.core.instrument.binder.cache.CaffeineCacheMetrics; import org.springframework.cache.caffeine.CaffeineCache; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java index f280cbe99762..92894ec0f45c 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java @@ -19,9 +19,9 @@ import java.lang.reflect.Method; import com.hazelcast.spring.cache.HazelcastCache; -import io.micrometer.binder.cache.HazelcastCacheMetrics; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.binder.MeterBinder; +import io.micrometer.core.instrument.binder.cache.HazelcastCacheMetrics; import org.springframework.util.ReflectionUtils; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProvider.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProvider.java index 5e91fb0f1eb0..32550e45f8bc 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProvider.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProvider.java @@ -16,9 +16,9 @@ package org.springframework.boot.actuate.metrics.cache; -import io.micrometer.binder.cache.JCacheMetrics; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.binder.MeterBinder; +import io.micrometer.core.instrument.binder.cache.JCacheMetrics; import org.springframework.cache.jcache.JCacheCache; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListener.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListener.java index 90d682b34ae6..3c6cc84cb463 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListener.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -123,7 +123,7 @@ private void registerGauge(String name, String description, Duration timeTaken, private Iterable createTagsFrom(SpringApplication springApplication) { Class mainClass = springApplication.getMainApplicationClass(); - return (mainClass != null) ? this.tags.and("main-application-class", mainClass.getName()) : this.tags; + return (mainClass != null) ? this.tags.and("main.application.class", mainClass.getName()) : this.tags; } } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/system/DiskSpaceMetricsBinder.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/system/DiskSpaceMetricsBinder.java index b5eba5f8a130..d2bcf25ce0d4 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/system/DiskSpaceMetricsBinder.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/system/DiskSpaceMetricsBinder.java @@ -19,10 +19,10 @@ import java.io.File; import java.util.List; -import io.micrometer.binder.system.DiskSpaceMetrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.binder.MeterBinder; +import io.micrometer.core.instrument.binder.system.DiskSpaceMetrics; import org.springframework.util.Assert; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/client/RestTemplateExchangeTags.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/client/RestTemplateExchangeTags.java index df7c74a50cd7..f0043f5b9e0f 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/client/RestTemplateExchangeTags.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/client/RestTemplateExchangeTags.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -97,7 +97,7 @@ private static String getStatusMessage(ClientHttpResponse response) { if (response == null) { return "CLIENT_ERROR"; } - return String.valueOf(response.getRawStatusCode()); + return String.valueOf(response.getStatusCode().value()); } catch (IOException ex) { return "IO_ERROR"; @@ -105,17 +105,17 @@ private static String getStatusMessage(ClientHttpResponse response) { } /** - * Create a {@code clientName} {@code Tag} derived from the {@link URI#getHost host} + * Create a {@code client.name} {@code Tag} derived from the {@link URI#getHost host} * of the {@link HttpRequest#getURI() URI} of the given {@code request}. * @param request the request - * @return the clientName tag + * @return the client.name tag */ public static Tag clientName(HttpRequest request) { String host = request.getURI().getHost(); if (host == null) { host = "none"; } - return Tag.of("clientName", host); + return Tag.of("client.name", host); } /** @@ -128,7 +128,7 @@ public static Tag clientName(HttpRequest request) { public static Tag outcome(ClientHttpResponse response) { try { if (response != null) { - return Outcome.forStatus(response.getRawStatusCode()).asTag(); + return Outcome.forStatus(response.getStatusCode().value()).asTag(); } } catch (IOException ex) { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyConnectionMetricsBinder.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyConnectionMetricsBinder.java index 662dd2ad2307..2f3483da5850 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyConnectionMetricsBinder.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyConnectionMetricsBinder.java @@ -18,9 +18,9 @@ import java.util.Collections; -import io.micrometer.binder.jetty.JettyConnectionMetrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.binder.jetty.JettyConnectionMetrics; import org.eclipse.jetty.server.Server; /** diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyServerThreadPoolMetricsBinder.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyServerThreadPoolMetricsBinder.java index 4801f05ebd58..2297b4f96ae4 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyServerThreadPoolMetricsBinder.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyServerThreadPoolMetricsBinder.java @@ -18,9 +18,9 @@ import java.util.Collections; -import io.micrometer.binder.jetty.JettyServerThreadPoolMetrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.binder.jetty.JettyServerThreadPoolMetrics; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.thread.ThreadPool; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettySslHandshakeMetricsBinder.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettySslHandshakeMetricsBinder.java index f590d24ffe9c..f4c81814a05c 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettySslHandshakeMetricsBinder.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettySslHandshakeMetricsBinder.java @@ -18,9 +18,9 @@ import java.util.Collections; -import io.micrometer.binder.jetty.JettySslHandshakeMetrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.binder.jetty.JettySslHandshakeMetrics; import org.eclipse.jetty.server.Server; /** diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTags.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTags.java index 6d0af88c6b7e..ac11b00e39be 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTags.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTags.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -45,7 +45,7 @@ public final class WebClientExchangeTags { private static final Pattern PATTERN_BEFORE_PATH = Pattern.compile("^https?://[^/]+/"); - private static final Tag CLIENT_NAME_NONE = Tag.of("clientName", "none"); + private static final Tag CLIENT_NAME_NONE = Tag.of("client.name", "none"); private WebClientExchangeTags() { } @@ -86,7 +86,7 @@ private static String extractPath(String url) { */ public static Tag status(ClientResponse response, Throwable throwable) { if (response != null) { - return Tag.of("status", String.valueOf(response.rawStatusCode())); + return Tag.of("status", String.valueOf(response.statusCode().value())); } if (throwable != null) { return (throwable instanceof IOException) ? IO_ERROR : CLIENT_ERROR; @@ -95,18 +95,18 @@ public static Tag status(ClientResponse response, Throwable throwable) { } /** - * Create a {@code clientName} {@code Tag} derived from the + * Create a {@code client.name} {@code Tag} derived from the * {@link java.net.URI#getHost host} of the {@link ClientRequest#url() URL} of the * given {@code request}. * @param request the request - * @return the clientName tag + * @return the client.name tag */ public static Tag clientName(ClientRequest request) { String host = request.url().getHost(); if (host == null) { return CLIENT_NAME_NONE; } - return Tag.of("clientName", host); + return Tag.of("client.name", host); } /** @@ -117,7 +117,7 @@ public static Tag clientName(ClientRequest request) { * @since 2.2.0 */ public static Tag outcome(ClientResponse response) { - Outcome outcome = (response != null) ? Outcome.forStatus(response.rawStatusCode()) : Outcome.UNKNOWN; + Outcome outcome = (response != null) ? Outcome.forStatus(response.statusCode().value()) : Outcome.UNKNOWN; return outcome.asTag(); } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTags.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTags.java index ce9205f9d0f1..7b55fff6b482 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTags.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTags.java @@ -25,7 +25,7 @@ import org.springframework.boot.actuate.metrics.http.Outcome; import org.springframework.http.HttpStatus; -import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.http.HttpStatusCode; import org.springframework.util.StringUtils; import org.springframework.web.reactive.HandlerMapping; import org.springframework.web.server.ServerWebExchange; @@ -80,7 +80,7 @@ public static Tag method(ServerWebExchange exchange) { * @return the status tag derived from the response status */ public static Tag status(ServerWebExchange exchange) { - HttpStatus status = exchange.getResponse().getStatusCode(); + HttpStatusCode status = exchange.getResponse().getStatusCode(); if (status == null) { status = HttpStatus.OK; } @@ -122,7 +122,7 @@ public static Tag uri(ServerWebExchange exchange, boolean ignoreTrailingSlash) { } return Tag.of("uri", patternString); } - HttpStatus status = exchange.getResponse().getStatusCode(); + HttpStatusCode status = exchange.getResponse().getStatusCode(); if (status != null) { if (status.is3xxRedirection()) { return URI_REDIRECTION; @@ -181,19 +181,9 @@ public static Tag outcome(ServerWebExchange exchange, Throwable exception) { return Outcome.UNKNOWN.asTag(); } } - Integer statusCode = extractStatusCode(exchange); - Outcome outcome = (statusCode != null) ? Outcome.forStatus(statusCode) : Outcome.SUCCESS; + HttpStatusCode statusCode = exchange.getResponse().getStatusCode(); + Outcome outcome = (statusCode != null) ? Outcome.forStatus(statusCode.value()) : Outcome.SUCCESS; return outcome.asTag(); } - private static Integer extractStatusCode(ServerWebExchange exchange) { - ServerHttpResponse response = exchange.getResponse(); - Integer statusCode = response.getRawStatusCode(); - if (statusCode != null) { - return statusCode; - } - HttpStatus status = response.getStatusCode(); - return (status != null) ? status.value() : null; - } - } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/tomcat/TomcatMetricsBinder.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/tomcat/TomcatMetricsBinder.java index 1de4181edaf2..45ad5a4acf5d 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/tomcat/TomcatMetricsBinder.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/tomcat/TomcatMetricsBinder.java @@ -18,9 +18,9 @@ import java.util.Collections; -import io.micrometer.binder.tomcat.TomcatMetrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.binder.tomcat.TomcatMetrics; import org.apache.catalina.Container; import org.apache.catalina.Context; import org.apache.catalina.Manager; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicatorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicatorTests.java index c1e56b7e56c9..9c6ab674c132 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicatorTests.java @@ -16,6 +16,7 @@ package org.springframework.boot.actuate.elasticsearch; +import java.time.Duration; import java.util.Map; import okhttp3.mockwebserver.MockResponse; @@ -44,6 +45,8 @@ */ class ElasticsearchReactiveHealthIndicatorTests { + private static final Duration TIMEOUT = Duration.ofSeconds(5); + private MockWebServer server; private ElasticsearchReactiveHealthIndicator healthIndicator; @@ -65,7 +68,7 @@ void shutdown() throws Exception { @Test void elasticsearchIsUp() { setupMockResponse(200, "green"); - Health health = this.healthIndicator.health().block(); + Health health = this.healthIndicator.health().block(TIMEOUT); assertThat(health.getStatus()).isEqualTo(Status.UP); assertHealthDetailsWithStatus(health.getDetails(), "green"); } @@ -73,7 +76,7 @@ void elasticsearchIsUp() { @Test void elasticsearchWithYellowStatusIsUp() { setupMockResponse(200, "yellow"); - Health health = this.healthIndicator.health().block(); + Health health = this.healthIndicator.health().block(TIMEOUT); assertThat(health.getStatus()).isEqualTo(Status.UP); assertHealthDetailsWithStatus(health.getDetails(), "yellow"); } @@ -81,7 +84,7 @@ void elasticsearchWithYellowStatusIsUp() { @Test void elasticsearchIsDown() throws Exception { this.server.shutdown(); - Health health = this.healthIndicator.health().block(); + Health health = this.healthIndicator.health().block(TIMEOUT); assertThat(health.getStatus()).isEqualTo(Status.DOWN); assertThat(health.getDetails().get("error")).asString() .contains("org.springframework.data.elasticsearch.client.NoReachableHostException"); @@ -93,7 +96,7 @@ void elasticsearchIsDownByResponseCode() { // to "/" this.server.enqueue(new MockResponse().setResponseCode(HttpStatus.OK.value())); this.server.enqueue(new MockResponse().setResponseCode(HttpStatus.INTERNAL_SERVER_ERROR.value())); - Health health = this.healthIndicator.health().block(); + Health health = this.healthIndicator.health().block(TIMEOUT); assertThat(health.getStatus()).isEqualTo(Status.DOWN); assertThat(health.getDetails().get("statusCode")).asString().isEqualTo("500"); assertThat(health.getDetails().get("reasonPhrase")).asString().isEqualTo("Internal Server Error"); @@ -102,7 +105,7 @@ void elasticsearchIsDownByResponseCode() { @Test void elasticsearchIsOutOfServiceByStatus() { setupMockResponse(200, "red"); - Health health = this.healthIndicator.health().block(); + Health health = this.healthIndicator.health().block(TIMEOUT); assertThat(health.getStatus()).isEqualTo(Status.OUT_OF_SERVICE); assertHealthDetailsWithStatus(health.getDetails(), "red"); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicatorTests.java similarity index 90% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorTests.java rename to spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicatorTests.java index c283c049e2b3..a718c6dc9119 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicatorTests.java @@ -37,16 +37,16 @@ import static org.mockito.Mockito.mock; /** - * Tests for {@link ElasticsearchRestHealthIndicator}. + * Tests for {@link ElasticsearchRestClientHealthIndicator}. * * @author Artsiom Yudovin * @author Filip Hrisafov */ -class ElasticsearchRestHealthIndicatorTests { +class ElasticsearchRestClientHealthIndicatorTests { private final RestClient restClient = mock(RestClient.class); - private final ElasticsearchRestHealthIndicator elasticsearchRestHealthIndicator = new ElasticsearchRestHealthIndicator( + private final ElasticsearchRestClientHealthIndicator elasticsearchRestClientHealthIndicator = new ElasticsearchRestClientHealthIndicator( this.restClient); @Test @@ -59,7 +59,7 @@ void elasticsearchIsUp() throws IOException { given(response.getStatusLine()).willReturn(statusLine); given(response.getEntity()).willReturn(httpEntity); given(this.restClient.performRequest(any(Request.class))).willReturn(response); - Health health = this.elasticsearchRestHealthIndicator.health(); + Health health = this.elasticsearchRestClientHealthIndicator.health(); assertThat(health.getStatus()).isEqualTo(Status.UP); assertHealthDetailsWithStatus(health.getDetails(), "green"); } @@ -74,7 +74,7 @@ void elasticsearchWithYellowStatusIsUp() throws IOException { given(response.getStatusLine()).willReturn(statusLine); given(response.getEntity()).willReturn(httpEntity); given(this.restClient.performRequest(any(Request.class))).willReturn(response); - Health health = this.elasticsearchRestHealthIndicator.health(); + Health health = this.elasticsearchRestClientHealthIndicator.health(); assertThat(health.getStatus()).isEqualTo(Status.UP); assertHealthDetailsWithStatus(health.getDetails(), "yellow"); } @@ -82,7 +82,7 @@ void elasticsearchWithYellowStatusIsUp() throws IOException { @Test void elasticsearchIsDown() throws IOException { given(this.restClient.performRequest(any(Request.class))).willThrow(new IOException("Couldn't connect")); - Health health = this.elasticsearchRestHealthIndicator.health(); + Health health = this.elasticsearchRestClientHealthIndicator.health(); assertThat(health.getStatus()).isEqualTo(Status.DOWN); assertThat(health.getDetails()).contains(entry("error", "java.io.IOException: Couldn't connect")); } @@ -95,7 +95,7 @@ void elasticsearchIsDownByResponseCode() throws IOException { given(statusLine.getReasonPhrase()).willReturn("Internal server error"); given(response.getStatusLine()).willReturn(statusLine); given(this.restClient.performRequest(any(Request.class))).willReturn(response); - Health health = this.elasticsearchRestHealthIndicator.health(); + Health health = this.elasticsearchRestClientHealthIndicator.health(); assertThat(health.getStatus()).isEqualTo(Status.DOWN); assertThat(health.getDetails()).contains(entry("statusCode", 500), entry("reasonPhrase", "Internal server error")); @@ -111,7 +111,7 @@ void elasticsearchIsOutOfServiceByStatus() throws IOException { given(response.getStatusLine()).willReturn(statusLine); given(response.getEntity()).willReturn(httpEntity); given(this.restClient.performRequest(any(Request.class))).willReturn(response); - Health health = this.elasticsearchRestHealthIndicator.health(); + Health health = this.elasticsearchRestClientHealthIndicator.health(); assertThat(health.getStatus()).isEqualTo(Status.OUT_OF_SERVICE); assertHealthDetailsWithStatus(health.getDetails(), "red"); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java index 583cae025846..b29425aeab72 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java @@ -21,9 +21,9 @@ import java.util.Map; import com.fasterxml.jackson.databind.ObjectMapper; -import io.micrometer.binder.jvm.JvmMemoryMetrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.MockClock; +import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; import io.micrometer.core.instrument.simple.SimpleConfig; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProviderTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProviderTests.java index d4246cf3402e..bca5ce345b7c 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProviderTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProviderTests.java @@ -19,8 +19,8 @@ import java.util.Collections; import com.github.benmanes.caffeine.cache.Caffeine; -import io.micrometer.binder.cache.CaffeineCacheMetrics; import io.micrometer.core.instrument.binder.MeterBinder; +import io.micrometer.core.instrument.binder.cache.CaffeineCacheMetrics; import org.junit.jupiter.api.Test; import org.springframework.cache.caffeine.CaffeineCache; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderTests.java index d5b57e21a494..737e8b855b9e 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderTests.java @@ -20,8 +20,8 @@ import com.hazelcast.map.IMap; import com.hazelcast.spring.cache.HazelcastCache; -import io.micrometer.binder.cache.HazelcastCacheMetrics; import io.micrometer.core.instrument.binder.MeterBinder; +import io.micrometer.core.instrument.binder.cache.HazelcastCacheMetrics; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProviderTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProviderTests.java index 8d9a8f00158d..919dc5bb06c5 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProviderTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProviderTests.java @@ -20,8 +20,8 @@ import java.net.URISyntaxException; import java.util.Collections; -import io.micrometer.binder.cache.JCacheMetrics; import io.micrometer.core.instrument.binder.MeterBinder; +import io.micrometer.core.instrument.binder.cache.JCacheMetrics; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListenerTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListenerTests.java index 34763a6fbcdf..8c0cd13534a3 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListenerTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListenerTests.java @@ -118,7 +118,7 @@ private void assertMetricExistsWithValue(String metricName, long expectedValueIn private void assertMetricExistsWithCustomTagsAndValue(String metricName, Tags expectedCustomTags, Long expectedValueInMillis) { assertThat(this.registry.find(metricName) - .tags(Tags.concat(expectedCustomTags, "main-application-class", TestMainApplication.class.getName())) + .tags(Tags.concat(expectedCustomTags, "main.application.class", TestMainApplication.class.getName())) .timeGauge()).isNotNull().extracting((m) -> m.value(TimeUnit.MILLISECONDS)) .isEqualTo(expectedValueInMillis.doubleValue()); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/RestTemplateExchangeTagsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/RestTemplateExchangeTagsTests.java index 17be58c70317..1a495a841899 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/RestTemplateExchangeTagsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/RestTemplateExchangeTagsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -17,11 +17,14 @@ package org.springframework.boot.actuate.metrics.web.client; import java.io.IOException; +import java.net.URI; import io.micrometer.core.instrument.Tag; import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpResponse; import org.springframework.mock.http.client.MockClientHttpResponse; @@ -81,7 +84,7 @@ void outcomeTagIsServerErrorWhenResponseIs5xx() { @Test void outcomeTagIsUnknownWhenResponseThrowsIOException() throws Exception { ClientHttpResponse response = mock(ClientHttpResponse.class); - given(response.getRawStatusCode()).willThrow(IOException.class); + given(response.getStatusCode()).willThrow(IOException.class); Tag tag = RestTemplateExchangeTags.outcome(response); assertThat(tag.getValue()).isEqualTo("UNKNOWN"); } @@ -89,7 +92,7 @@ void outcomeTagIsUnknownWhenResponseThrowsIOException() throws Exception { @Test void outcomeTagIsClientErrorWhenResponseIsNonStandardInClientSeries() throws IOException { ClientHttpResponse response = mock(ClientHttpResponse.class); - given(response.getRawStatusCode()).willReturn(490); + given(response.getStatusCode()).willReturn(HttpStatusCode.valueOf(490)); Tag tag = RestTemplateExchangeTags.outcome(response); assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR"); } @@ -97,9 +100,17 @@ void outcomeTagIsClientErrorWhenResponseIsNonStandardInClientSeries() throws IOE @Test void outcomeTagIsUnknownWhenResponseStatusIsInUnknownSeries() throws IOException { ClientHttpResponse response = mock(ClientHttpResponse.class); - given(response.getRawStatusCode()).willReturn(701); + given(response.getStatusCode()).willReturn(HttpStatusCode.valueOf(701)); Tag tag = RestTemplateExchangeTags.outcome(response); assertThat(tag.getValue()).isEqualTo("UNKNOWN"); } + @Test + void clientNameTagIsHostOfRequestUri() throws IOException { + ClientHttpRequest request = mock(ClientHttpRequest.class); + given(request.getURI()).willReturn(URI.create("https://example.org")); + Tag tag = RestTemplateExchangeTags.clientName(request); + assertThat(tag).isEqualTo(Tag.of("client.name", "example.org")); + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/DefaultWebClientExchangeTagsProviderTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/DefaultWebClientExchangeTagsProviderTests.java index 5358fd357762..d01b7d9cb7af 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/DefaultWebClientExchangeTagsProviderTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/DefaultWebClientExchangeTagsProviderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-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. @@ -54,14 +54,14 @@ void setup() { this.request = ClientRequest.create(HttpMethod.GET, URI.create("https://example.org/projects/spring-boot")) .attribute(URI_TEMPLATE_ATTRIBUTE, "https://example.org/projects/{project}").build(); this.response = mock(ClientResponse.class); - given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value()); + given(this.response.statusCode()).willReturn(HttpStatus.OK); } @Test void tagsShouldBePopulated() { Iterable tags = this.tagsProvider.tags(this.request, this.response, null); assertThat(tags).containsExactlyInAnyOrder(Tag.of("method", "GET"), Tag.of("uri", "/projects/{project}"), - Tag.of("clientName", "example.org"), Tag.of("status", "200"), Tag.of("outcome", "SUCCESS")); + Tag.of("client.name", "example.org"), Tag.of("status", "200"), Tag.of("outcome", "SUCCESS")); } @Test @@ -70,28 +70,28 @@ void tagsWhenNoUriTemplateShouldProvideUriPath() { .create(HttpMethod.GET, URI.create("https://example.org/projects/spring-boot")).build(); Iterable tags = this.tagsProvider.tags(request, this.response, null); assertThat(tags).containsExactlyInAnyOrder(Tag.of("method", "GET"), Tag.of("uri", "/projects/spring-boot"), - Tag.of("clientName", "example.org"), Tag.of("status", "200"), Tag.of("outcome", "SUCCESS")); + Tag.of("client.name", "example.org"), Tag.of("status", "200"), Tag.of("outcome", "SUCCESS")); } @Test void tagsWhenIoExceptionShouldReturnIoErrorStatus() { Iterable tags = this.tagsProvider.tags(this.request, null, new IOException()); assertThat(tags).containsExactlyInAnyOrder(Tag.of("method", "GET"), Tag.of("uri", "/projects/{project}"), - Tag.of("clientName", "example.org"), Tag.of("status", "IO_ERROR"), Tag.of("outcome", "UNKNOWN")); + Tag.of("client.name", "example.org"), Tag.of("status", "IO_ERROR"), Tag.of("outcome", "UNKNOWN")); } @Test void tagsWhenExceptionShouldReturnClientErrorStatus() { Iterable tags = this.tagsProvider.tags(this.request, null, new IllegalArgumentException()); assertThat(tags).containsExactlyInAnyOrder(Tag.of("method", "GET"), Tag.of("uri", "/projects/{project}"), - Tag.of("clientName", "example.org"), Tag.of("status", "CLIENT_ERROR"), Tag.of("outcome", "UNKNOWN")); + Tag.of("client.name", "example.org"), Tag.of("status", "CLIENT_ERROR"), Tag.of("outcome", "UNKNOWN")); } @Test void tagsWhenCancelledRequestShouldReturnClientErrorStatus() { Iterable tags = this.tagsProvider.tags(this.request, null, null); assertThat(tags).containsExactlyInAnyOrder(Tag.of("method", "GET"), Tag.of("uri", "/projects/{project}"), - Tag.of("clientName", "example.org"), Tag.of("status", "CLIENT_ERROR"), Tag.of("outcome", "UNKNOWN")); + Tag.of("client.name", "example.org"), Tag.of("status", "CLIENT_ERROR"), Tag.of("outcome", "UNKNOWN")); } } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/MetricsWebClientFilterFunctionTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/MetricsWebClientFilterFunctionTests.java index b651560ec57c..f762b6850f7d 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/MetricsWebClientFilterFunctionTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/MetricsWebClientFilterFunctionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -75,7 +75,7 @@ void setup() { void filterShouldRecordTimer() { ClientRequest request = ClientRequest .create(HttpMethod.GET, URI.create("https://example.com/projects/spring-boot")).build(); - given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value()); + given(this.response.statusCode()).willReturn(HttpStatus.OK); this.filterFunction.filter(request, this.exchange).block(Duration.ofSeconds(5)); assertThat(this.registry.get("http.client.requests") .tags("method", "GET", "uri", "/projects/spring-boot", "status", "200").timer().count()).isEqualTo(1); @@ -86,7 +86,7 @@ void filterWhenUriTemplatePresentShouldRecordTimer() { ClientRequest request = ClientRequest .create(HttpMethod.GET, URI.create("https://example.com/projects/spring-boot")) .attribute(URI_TEMPLATE_ATTRIBUTE, "/projects/{project}").build(); - given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value()); + given(this.response.statusCode()).willReturn(HttpStatus.OK); this.filterFunction.filter(request, this.exchange).block(Duration.ofSeconds(5)); assertThat(this.registry.get("http.client.requests") .tags("method", "GET", "uri", "/projects/{project}", "status", "200").timer().count()).isEqualTo(1); @@ -120,7 +120,7 @@ void filterWhenExceptionThrownShouldRecordTimer() { void filterWhenCancelThrownShouldRecordTimer() { ClientRequest request = ClientRequest .create(HttpMethod.GET, URI.create("https://example.com/projects/spring-boot")).build(); - given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value()); + given(this.response.statusCode()).willReturn(HttpStatus.OK); Mono filter = this.filterFunction.filter(request, this.exchange); StepVerifier.create(filter).thenCancel().verify(Duration.ofSeconds(5)); assertThat(this.registry.get("http.client.requests") @@ -135,7 +135,7 @@ void filterWhenCancelThrownShouldRecordTimer() { void filterWhenCancelAfterResponseThrownShouldNotRecordTimer() { ClientRequest request = ClientRequest .create(HttpMethod.GET, URI.create("https://example.com/projects/spring-boot")).build(); - given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value()); + given(this.response.statusCode()).willReturn(HttpStatus.OK); Mono filter = this.filterFunction.filter(request, this.exchange); StepVerifier.create(filter).expectNextCount(1).thenCancel().verify(Duration.ofSeconds(5)); assertThat(this.registry.get("http.client.requests") diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTagsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTagsTests.java index 3ba0a4eed9e8..9889ba7d2174 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTagsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTagsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-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. @@ -25,6 +25,7 @@ import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.web.reactive.function.client.ClientRequest; import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.WebClient; @@ -88,12 +89,12 @@ void uriWhenTemplateIsMissingShouldReturnPathWithQueryParams() { @Test void clientName() { - assertThat(WebClientExchangeTags.clientName(this.request)).isEqualTo(Tag.of("clientName", "example.org")); + assertThat(WebClientExchangeTags.clientName(this.request)).isEqualTo(Tag.of("client.name", "example.org")); } @Test void status() { - given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value()); + given(this.response.statusCode()).willReturn(HttpStatus.OK); assertThat(WebClientExchangeTags.status(this.response, null)).isEqualTo(Tag.of("status", "200")); } @@ -110,7 +111,7 @@ void statusWhenClientException() { @Test void statusWhenNonStandard() { - given(this.response.rawStatusCode()).willReturn(490); + given(this.response.statusCode()).willReturn(HttpStatusCode.valueOf(490)); assertThat(WebClientExchangeTags.status(this.response, null)).isEqualTo(Tag.of("status", "490")); } @@ -127,49 +128,49 @@ void outcomeTagIsUnknownWhenResponseIsNull() { @Test void outcomeTagIsInformationalWhenResponseIs1xx() { - given(this.response.rawStatusCode()).willReturn(HttpStatus.CONTINUE.value()); + given(this.response.statusCode()).willReturn(HttpStatus.CONTINUE); Tag tag = WebClientExchangeTags.outcome(this.response); assertThat(tag.getValue()).isEqualTo("INFORMATIONAL"); } @Test void outcomeTagIsSuccessWhenResponseIs2xx() { - given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value()); + given(this.response.statusCode()).willReturn(HttpStatus.OK); Tag tag = WebClientExchangeTags.outcome(this.response); assertThat(tag.getValue()).isEqualTo("SUCCESS"); } @Test void outcomeTagIsRedirectionWhenResponseIs3xx() { - given(this.response.rawStatusCode()).willReturn(HttpStatus.MOVED_PERMANENTLY.value()); + given(this.response.statusCode()).willReturn(HttpStatus.MOVED_PERMANENTLY); Tag tag = WebClientExchangeTags.outcome(this.response); assertThat(tag.getValue()).isEqualTo("REDIRECTION"); } @Test void outcomeTagIsClientErrorWhenResponseIs4xx() { - given(this.response.rawStatusCode()).willReturn(HttpStatus.BAD_REQUEST.value()); + given(this.response.statusCode()).willReturn(HttpStatus.BAD_REQUEST); Tag tag = WebClientExchangeTags.outcome(this.response); assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR"); } @Test void outcomeTagIsServerErrorWhenResponseIs5xx() { - given(this.response.rawStatusCode()).willReturn(HttpStatus.BAD_GATEWAY.value()); + given(this.response.statusCode()).willReturn(HttpStatus.BAD_GATEWAY); Tag tag = WebClientExchangeTags.outcome(this.response); assertThat(tag.getValue()).isEqualTo("SERVER_ERROR"); } @Test void outcomeTagIsClientErrorWhenResponseIsNonStandardInClientSeries() { - given(this.response.rawStatusCode()).willReturn(490); + given(this.response.statusCode()).willReturn(HttpStatusCode.valueOf(490)); Tag tag = WebClientExchangeTags.outcome(this.response); assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR"); } @Test void outcomeTagIsUnknownWhenResponseStatusIsInUnknownSeries() { - given(this.response.rawStatusCode()).willReturn(701); + given(this.response.statusCode()).willReturn(HttpStatusCode.valueOf(701)); Tag tag = WebClientExchangeTags.outcome(this.response); assertThat(tag.getValue()).isEqualTo("UNKNOWN"); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTagsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTagsTests.java index c6e04f9a6ebc..c82b1a22e3d4 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTagsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTagsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -153,7 +153,7 @@ void outcomeTagIsSuccessWhenResponseStatusIsAvailableFromUnderlyingServer() { ServerHttpRequest request = mock(ServerHttpRequest.class); ServerHttpResponse response = mock(ServerHttpResponse.class); given(response.getStatusCode()).willReturn(HttpStatus.OK); - given(response.getRawStatusCode()).willReturn(null); + given(response.getStatusCode().value()).willReturn(null); given(exchange.getRequest()).willReturn(request); given(exchange.getResponse()).willReturn(response); Tag tag = WebFluxTags.outcome(exchange, null); diff --git a/spring-boot-project/spring-boot-autoconfigure/build.gradle b/spring-boot-project/spring-boot-autoconfigure/build.gradle index 8a8a20c37aa5..0e741597ee0b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-autoconfigure/build.gradle @@ -214,6 +214,7 @@ dependencies { testImplementation("org.junit.jupiter:junit-jupiter") testImplementation("org.mockito:mockito-core") testImplementation("org.mockito:mockito-junit-jupiter") + testImplementation("org.skyscreamer:jsonassert") testImplementation("org.springframework:spring-test") testImplementation("org.springframework.kafka:spring-kafka-test") testImplementation("org.springframework.security:spring-security-test") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzer.java index ef174a22af4b..728a0c91e866 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzer.java @@ -26,9 +26,7 @@ import java.util.Set; import java.util.stream.Collectors; -import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.InjectionPoint; import org.springframework.beans.factory.NoSuchBeanDefinitionException; @@ -57,18 +55,17 @@ * * @author Stephane Nicoll * @author Phillip Webb + * @author Scott Frederick */ -class NoSuchBeanDefinitionFailureAnalyzer extends AbstractInjectionFailureAnalyzer - implements BeanFactoryAware { +class NoSuchBeanDefinitionFailureAnalyzer extends AbstractInjectionFailureAnalyzer { - private ConfigurableListableBeanFactory beanFactory; + private final ConfigurableListableBeanFactory beanFactory; - private MetadataReaderFactory metadataReaderFactory; + private final MetadataReaderFactory metadataReaderFactory; - private ConditionEvaluationReport report; + private final ConditionEvaluationReport report; - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + NoSuchBeanDefinitionFailureAnalyzer(BeanFactory beanFactory) { Assert.isInstanceOf(ConfigurableListableBeanFactory.class, beanFactory); this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; this.metadataReaderFactory = new CachingMetadataReaderFactory(this.beanFactory.getBeanClassLoader()); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfiguration.java index 988f5115e7d7..a219abf00025 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfiguration.java @@ -22,6 +22,8 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientBuilderConfiguration; +import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientConfiguration; +import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientFromRestHighLevelClientConfiguration; import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientSnifferConfiguration; import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestHighLevelClientConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -38,6 +40,7 @@ @ConditionalOnClass(RestClientBuilder.class) @EnableConfigurationProperties({ ElasticsearchProperties.class, ElasticsearchRestClientProperties.class }) @Import({ RestClientBuilderConfiguration.class, RestHighLevelClientConfiguration.class, + RestClientFromRestHighLevelClientConfiguration.class, RestClientConfiguration.class, RestClientSnifferConfiguration.class }) public class ElasticsearchRestClientAutoConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientConfigurations.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientConfigurations.java index 31776e8096a7..903a4dc23f31 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientConfigurations.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientConfigurations.java @@ -35,6 +35,7 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.context.annotation.Bean; @@ -45,6 +46,7 @@ * Elasticsearch rest client configurations. * * @author Stephane Nicoll + * @author Filip Hrisafov */ class ElasticsearchRestClientConfigurations { @@ -123,15 +125,39 @@ org.elasticsearch.client.RestHighLevelClient elasticsearchRestHighLevelClient( @SuppressWarnings("deprecation") @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(Sniffer.class) + @ConditionalOnClass(org.elasticsearch.client.RestHighLevelClient.class) @ConditionalOnSingleCandidate(org.elasticsearch.client.RestHighLevelClient.class) + @ConditionalOnMissingBean(RestClient.class) + static class RestClientFromRestHighLevelClientConfiguration { + + @Bean + RestClient elasticsearchRestClient(org.elasticsearch.client.RestHighLevelClient restHighLevelClient) { + return restHighLevelClient.getLowLevelClient(); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnMissingClass("org.elasticsearch.client.RestHighLevelClient") + @ConditionalOnMissingBean(RestClient.class) + static class RestClientConfiguration { + + @Bean + RestClient elasticsearchRestClient(RestClientBuilder restClientBuilder) { + return restClientBuilder.build(); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(Sniffer.class) + @ConditionalOnSingleCandidate(RestClient.class) static class RestClientSnifferConfiguration { @Bean @ConditionalOnMissingBean - Sniffer elasticsearchSniffer(org.elasticsearch.client.RestHighLevelClient client, - ElasticsearchRestClientProperties properties) { - SnifferBuilder builder = Sniffer.builder(client.getLowLevelClient()); + Sniffer elasticsearchSniffer(RestClient client, ElasticsearchRestClientProperties properties) { + SnifferBuilder builder = Sniffer.builder(client); PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); Duration interval = properties.getSniffer().getInterval(); map.from(interval).asInt(Duration::toMillis).to(builder::setSniffIntervalMillis); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java index 711a12bce70c..96da586a59ce 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java @@ -325,15 +325,6 @@ private void configureJavaMigrations(FluentConfiguration flyway, List locations) { - for (String location : locations) { - if (resourceLoader.getResource(normalizePrefix(location)).exists()) { - return true; - } - } - return false; - } - private String normalizePrefix(String location) { return location.replace("filesystem:", "file:"); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java index cd85b0ede8a1..b789a4ed7976 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -67,7 +67,7 @@ public static class Registration { /** * Remote SAML Identity Provider. */ - private final Identityprovider identityprovider = new Identityprovider(); + private final AssertingParty assertingParty = new AssertingParty(); public String getEntityId() { return this.entityId; @@ -89,8 +89,8 @@ public Decryption getDecryption() { return this.decryption; } - public Identityprovider getIdentityprovider() { - return this.identityprovider; + public AssertingParty getAssertingParty() { + return this.assertingParty; } public static class Acs { @@ -224,7 +224,7 @@ public void setCertificateLocation(Resource certificate) { /** * Represents a remote Identity Provider. */ - public static class Identityprovider { + public static class AssertingParty { /** * Unique identifier for the identity provider. diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java index f795bae223c5..fa54027b3ac8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -26,8 +26,9 @@ import java.util.stream.Collectors; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.AssertingParty; +import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.AssertingParty.Verification; import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.Decryption; -import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.Identityprovider.Verification; import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.Registration; import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.Registration.Signing; import org.springframework.boot.context.properties.PropertyMapper; @@ -71,19 +72,19 @@ private RelyingPartyRegistration asRegistration(Map.Entry } private RelyingPartyRegistration asRegistration(String id, Registration properties) { - boolean usingMetadata = StringUtils.hasText(properties.getIdentityprovider().getMetadataUri()); + boolean usingMetadata = StringUtils.hasText(properties.getAssertingParty().getMetadataUri()); Builder builder = (usingMetadata) ? RelyingPartyRegistrations - .fromMetadataLocation(properties.getIdentityprovider().getMetadataUri()).registrationId(id) + .fromMetadataLocation(properties.getAssertingParty().getMetadataUri()).registrationId(id) : RelyingPartyRegistration.withRegistrationId(id); builder.assertionConsumerServiceLocation(properties.getAcs().getLocation()); builder.assertionConsumerServiceBinding(properties.getAcs().getBinding()); - builder.assertingPartyDetails(mapIdentityProvider(properties, usingMetadata)); + builder.assertingPartyDetails(mapAssertingParty(properties.getAssertingParty(), usingMetadata)); builder.signingX509Credentials((credentials) -> properties.getSigning().getCredentials().stream() .map(this::asSigningCredential).forEach(credentials::add)); builder.decryptionX509Credentials((credentials) -> properties.getDecryption().getCredentials().stream() .map(this::asDecryptionCredential).forEach(credentials::add)); builder.assertingPartyDetails((details) -> details - .verificationX509Credentials((credentials) -> properties.getIdentityprovider().getVerification() + .verificationX509Credentials((credentials) -> properties.getAssertingParty().getVerification() .getCredentials().stream().map(this::asVerificationCredential).forEach(credentials::add))); builder.entityId(properties.getEntityId()); RelyingPartyRegistration registration = builder.build(); @@ -92,16 +93,14 @@ private RelyingPartyRegistration asRegistration(String id, Registration properti return registration; } - private Consumer mapIdentityProvider(Registration properties, + private Consumer mapAssertingParty(AssertingParty assertingParty, boolean usingMetadata) { PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - Saml2RelyingPartyProperties.Identityprovider identityprovider = properties.getIdentityprovider(); return (details) -> { - map.from(identityprovider::getEntityId).to(details::entityId); - map.from(identityprovider.getSinglesignon()::getBinding).whenNonNull() - .to(details::singleSignOnServiceBinding); - map.from(identityprovider.getSinglesignon()::getUrl).to(details::singleSignOnServiceLocation); - map.from(identityprovider.getSinglesignon()::isSignRequest).when((signRequest) -> !usingMetadata) + map.from(assertingParty::getEntityId).to(details::entityId); + map.from(assertingParty.getSinglesignon()::getBinding).to(details::singleSignOnServiceBinding); + map.from(assertingParty.getSinglesignon()::getUrl).to(details::singleSignOnServiceLocation); + map.from(assertingParty.getSinglesignon()::isSignRequest).when((signRequest) -> !usingMetadata) .to(details::wantAuthnRequestsSigned); }; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionConfiguration.java index e31c794c8587..79e011594446 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-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. @@ -33,7 +33,7 @@ import org.springframework.session.data.redis.RedisIndexedSessionRepository; import org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction; import org.springframework.session.data.redis.config.ConfigureRedisAction; -import org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration; +import org.springframework.session.data.redis.config.annotation.web.http.RedisIndexedHttpSessionConfiguration; /** * Redis backed session configuration. @@ -66,7 +66,7 @@ ConfigureRedisAction configureRedisAction(RedisSessionProperties redisSessionPro } @Configuration(proxyBeanMethods = false) - public static class SpringBootRedisHttpSessionConfiguration extends RedisHttpSessionConfiguration { + public static class SpringBootRedisHttpSessionConfiguration extends RedisIndexedHttpSessionConfiguration { @Autowired public void customize(SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties, diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/AbstractErrorWebExceptionHandler.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/AbstractErrorWebExceptionHandler.java index 5bb9fd55db43..5fd010af20c0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/AbstractErrorWebExceptionHandler.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/AbstractErrorWebExceptionHandler.java @@ -320,7 +320,7 @@ protected void logError(ServerRequest request, ServerResponse response, Throwabl if (logger.isDebugEnabled()) { logger.debug(request.exchange().getLogPrefix() + formatError(throwable, request)); } - if (HttpStatus.resolve(response.rawStatusCode()) != null + if (HttpStatus.resolve(response.statusCode().value()) != null && response.statusCode().equals(HttpStatus.INTERNAL_SERVER_ERROR)) { logger.error(LogMessage.of(() -> String.format("%s 500 Server Error for %s", request.exchange().getLogPrefix(), formatRequest(request))), throwable); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index ee3ae9335351..4a8659962fca 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -243,6 +243,22 @@ "name": "server.ssl.trust-store-type", "description": "Type of the trust store." }, + { + "name": "server.ssl.certificate", + "description": "Path to a PEM-encoded SSL certificate file." + }, + { + "name": "server.ssl.certificate-private-key", + "description": "Path to a PEM-encoded private key file for the SSL certificate." + }, + { + "name": "server.ssl.trust-certificate", + "description": "Path to a PEM-encoded SSL certificate authority file." + }, + { + "name": "server.ssl.trust-certificate-private-key", + "description": "Path to a PEM-encoded private key file for the SSL certificate authority." + }, { "name": "server.tomcat.max-http-post-size", "type": "org.springframework.util.unit.DataSize", @@ -792,6 +808,41 @@ "defaultValue": "default" }, { + "name" : "spring.datasource.continue-on-error", + "type" : "java.lang.Boolean", + "deprecation" : { + "level" : "error", + "replacement": "spring.sql.init.continue-on-error" + } + }, { + "name" : "spring.datasource.data", + "type" : "java.util.List", + "deprecation" : { + "level" : "error", + "replacement": "spring.sql.init.data-locations" + } + }, { + "name" : "spring.datasource.data-password", + "type" : "java.lang.String", + "deprecation" : { + "level" : "error", + "replacement": "spring.sql.init.password" + } + }, { + "name" : "spring.datasource.data-username", + "type" : "java.lang.String", + "deprecation" : { + "level" : "error", + "replacement": "spring.sql.init.username" + } + }, { + "name" : "spring.datasource.initialization-mode", + "type" : "org.springframework.boot.jdbc.DataSourceInitializationMode", + "deprecation" : { + "level" : "error", + "replacement": "spring.sql.init.mode" + } + }, { "name": "spring.datasource.jmx-enabled", "type": "java.lang.Boolean", "description": "Whether to enable JMX support (if provided by the underlying pool).", @@ -800,8 +851,49 @@ "level": "error", "replacement": "spring.datasource.tomcat.jmx-enabled" } - }, - { + }, { + "name" : "spring.datasource.platform", + "type" : "java.lang.String", + "deprecation" : { + "level" : "error", + "replacement": "spring.sql.init.platform" + } + }, { + "name" : "spring.datasource.schema", + "type" : "java.util.List", + "deprecation" : { + "level" : "error", + "replacement": "spring.sql.init.schema-locations" + } + }, { + "name" : "spring.datasource.schema-password", + "type" : "java.lang.String", + "deprecation" : { + "level" : "error", + "replacement": "spring.sql.init.password" + } + }, { + "name" : "spring.datasource.schema-username", + "type" : "java.lang.String", + "deprecation" : { + "level" : "error", + "replacement": "spring.sql.init.username" + } + }, { + "name" : "spring.datasource.separator", + "type" : "java.lang.String", + "deprecation" : { + "level" : "error", + "replacement": "spring.sql.init.separator" + } + }, { + "name" : "spring.datasource.sql-script-encoding", + "type" : "java.nio.charset.Charset", + "deprecation" : { + "level" : "error", + "replacement": "spring.sql.init.encoding" + } + }, { "name": "spring.elasticsearch.jest.connection-timeout", "type": "java.time.Duration", "description": "Connection timeout.", diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzerTests.java index 7dfa8484ba7b..8c241c7178d3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzerTests.java @@ -46,10 +46,14 @@ * Tests for {@link NoSuchBeanDefinitionFailureAnalyzer}. * * @author Stephane Nicoll + * @author Scott Frederick */ class NoSuchBeanDefinitionFailureAnalyzerTests { - private final NoSuchBeanDefinitionFailureAnalyzer analyzer = new NoSuchBeanDefinitionFailureAnalyzer(); + private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + + private final NoSuchBeanDefinitionFailureAnalyzer analyzer = new NoSuchBeanDefinitionFailureAnalyzer( + this.context.getBeanFactory()); @Test void failureAnalysisForMultipleBeans() { @@ -208,11 +212,10 @@ private static void addExclusions(NoSuchBeanDefinitionFailureAnalyzer analyzer, } private FatalBeanException createFailure(Class config, String... environment) { - try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) { - this.analyzer.setBeanFactory(context.getBeanFactory()); - TestPropertyValues.of(environment).applyTo(context); - context.register(config); - context.refresh(); + try { + TestPropertyValues.of(environment).applyTo(this.context); + this.context.register(config); + this.context.refresh(); return null; } catch (FatalBeanException ex) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java index 24be99bfdc6b..e979c4d1d823 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java @@ -16,13 +16,19 @@ package org.springframework.boot.autoconfigure.elasticsearch; +import java.io.InputStream; import java.time.Duration; import java.util.HashMap; import java.util.Map; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.client.Request; import org.elasticsearch.client.RequestOptions; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; import org.junit.jupiter.api.Test; import org.testcontainers.elasticsearch.ElasticsearchContainer; import org.testcontainers.junit.jupiter.Container; @@ -40,6 +46,7 @@ * @author Brian Clozel * @author Vedran Pavic * @author Evgeniy Cheban + * @author Filip Hrisafov */ @Testcontainers(disabledWithoutDocker = true) class ElasticsearchRestClientAutoConfigurationIntegrationTests { @@ -53,7 +60,7 @@ class ElasticsearchRestClientAutoConfigurationIntegrationTests { @Test @SuppressWarnings("deprecation") - void restClientCanQueryElasticsearchNode() { + void restHighLevelClientCanQueryElasticsearchNode() { this.contextRunner .withPropertyValues("spring.elasticsearch.uris=" + elasticsearch.getHttpHostAddress(), "spring.elasticsearch.connection-timeout=120s", "spring.elasticsearch.socket-timeout=120s") @@ -70,4 +77,23 @@ void restClientCanQueryElasticsearchNode() { }); } + @Test + void restClientCanQueryElasticsearchNode() { + this.contextRunner + .withPropertyValues("spring.elasticsearch.uris=" + elasticsearch.getHttpHostAddress(), + "spring.elasticsearch.connection-timeout=120s", "spring.elasticsearch.socket-timeout=120s") + .run((context) -> { + RestClient client = context.getBean(RestClient.class); + Request index = new Request("PUT", "/test/_doc/2"); + index.setJsonEntity("{" + " \"a\": \"alpha\"," + " \"b\": \"bravo\"" + "}"); + client.performRequest(index); + Request getRequest = new Request("GET", "/test/_doc/2"); + Response response = client.performRequest(getRequest); + try (InputStream input = response.getEntity().getContent()) { + JsonNode result = new ObjectMapper().readTree(input); + assertThat(result.path("found").asBoolean()).isTrue(); + } + }); + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationTests.java index d92bd99a1135..3a8f1723a07c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationTests.java @@ -17,7 +17,6 @@ package org.springframework.boot.autoconfigure.elasticsearch; import java.time.Duration; -import java.util.Map; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; @@ -49,6 +48,7 @@ * @author Vedran Pavic * @author Evgeniy Cheban * @author Filip Hrisafov + * @author Andy Wilkinson */ @SuppressWarnings("deprecation") class ElasticsearchRestClientAutoConfigurationTests { @@ -57,19 +57,22 @@ class ElasticsearchRestClientAutoConfigurationTests { .withConfiguration(AutoConfigurations.of(ElasticsearchRestClientAutoConfiguration.class)); @Test - void configureShouldOnlyCreateHighLevelRestClient() { - this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(RestClient.class) - .hasSingleBean(RestClientBuilder.class) - .hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class)); - + void configureShouldCreateHighLevelAndLowLevelRestClients() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(RestClient.class) + .hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class) + .hasSingleBean(RestClientBuilder.class); + assertThat(context.getBean(RestClient.class)) + .isEqualTo(context.getBean(org.elasticsearch.client.RestHighLevelClient.class).getLowLevelClient()); + }); } @Test - void configureWithoutRestHighLevelClientShouldOnlyCreateRestClientBuilder() { + void configureWithoutRestHighLevelClientShouldOnlyCreateRestClientBuilderAndRestClient() { this.contextRunner.withClassLoader(new FilteredClassLoader(org.elasticsearch.client.RestHighLevelClient.class)) - .run((context) -> assertThat(context).doesNotHaveBean(RestClient.class) - .doesNotHaveBean(org.elasticsearch.client.RestHighLevelClient.class) - .hasSingleBean(RestClientBuilder.class)); + .run((context) -> assertThat(context).hasSingleBean(RestClient.class) + .hasSingleBean(RestClientBuilder.class) + .doesNotHaveBean(org.elasticsearch.client.RestHighLevelClient.class)); } @Test @@ -82,24 +85,33 @@ void configureWhenCustomRestClientShouldBackOff() { } @Test - void configureWhenCustomRestHighLevelClientShouldBackOff() { - this.contextRunner.withUserConfiguration(CustomRestHighLevelClientConfiguration.class).run( - (context) -> assertThat(context).hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class)); + void configureWhenCustomRestHighLevelClientShouldDefineRestClientFromCustomHighLevelClient() { + this.contextRunner.withUserConfiguration(CustomRestHighLevelClientConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class) + .hasSingleBean(RestClient.class).hasBean("elasticsearchRestClient").getBean(RestClient.class) + .isEqualTo(context.getBean(org.elasticsearch.client.RestHighLevelClient.class) + .getLowLevelClient())); } @Test - void configureWhenDefaultRestClientShouldCreateWhenNoUniqueRestHighLevelClient() { - this.contextRunner.withUserConfiguration(TwoCustomRestHighLevelClientConfiguration.class).run((context) -> { - Map restHighLevelClients = context - .getBeansOfType(org.elasticsearch.client.RestHighLevelClient.class); - assertThat(restHighLevelClients).hasSize(2); - }); + void configureWhenCustomRestHighLevelClientAndRestClientShouldBackOff() { + this.contextRunner.withUserConfiguration(CustomRestHighLevelClientWithRestClientConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class) + .hasBean("customRestHighLevelClient").hasSingleBean(RestClient.class) + .hasBean("customRestClient")); + } + + @Test + void configureWhenNoUniqueRestHighLevelClientShouldNotDefineRestClient() { + this.contextRunner.withUserConfiguration(TwoCustomRestHighLevelClientsConfiguration.class) + .run((context) -> assertThat(context).doesNotHaveBean(RestClient.class)); } @Test void configureWhenBuilderCustomizerShouldApply() { this.contextRunner.withUserConfiguration(BuilderCustomizerConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class); + assertThat(context).hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class) + .hasSingleBean(RestClient.class); org.elasticsearch.client.RestHighLevelClient restClient = context .getBean(org.elasticsearch.client.RestHighLevelClient.class); RestClient lowLevelClient = restClient.getLowLevelClient(); @@ -112,9 +124,8 @@ void configureWhenBuilderCustomizerShouldApply() { @Test void configureWithNoTimeoutsApplyDefaults() { this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class); - org.elasticsearch.client.RestHighLevelClient restClient = context - .getBean(org.elasticsearch.client.RestHighLevelClient.class); + assertThat(context).hasSingleBean(RestClient.class); + RestClient restClient = context.getBean(RestClient.class); assertTimeouts(restClient, Duration.ofMillis(RestClientBuilder.DEFAULT_CONNECT_TIMEOUT_MILLIS), Duration.ofMillis(RestClientBuilder.DEFAULT_SOCKET_TIMEOUT_MILLIS)); }); @@ -124,25 +135,23 @@ void configureWithNoTimeoutsApplyDefaults() { void configureWithCustomTimeouts() { this.contextRunner.withPropertyValues("spring.elasticsearch.connection-timeout=15s", "spring.elasticsearch.socket-timeout=1m").run((context) -> { - assertThat(context).hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class); - org.elasticsearch.client.RestHighLevelClient restClient = context - .getBean(org.elasticsearch.client.RestHighLevelClient.class); + assertThat(context).hasSingleBean(RestClient.class); + RestClient restClient = context.getBean(RestClient.class); assertTimeouts(restClient, Duration.ofSeconds(15), Duration.ofMinutes(1)); }); } - private static void assertTimeouts(org.elasticsearch.client.RestHighLevelClient restClient, Duration connectTimeout, - Duration readTimeout) { - assertThat(restClient.getLowLevelClient()).extracting("client.defaultConfig.socketTimeout") + private static void assertTimeouts(RestClient restClient, Duration connectTimeout, Duration readTimeout) { + assertThat(restClient).extracting("client.defaultConfig.socketTimeout") .isEqualTo(Math.toIntExact(readTimeout.toMillis())); - assertThat(restClient.getLowLevelClient()).extracting("client.defaultConfig.connectTimeout") + assertThat(restClient).extracting("client.defaultConfig.connectTimeout") .isEqualTo(Math.toIntExact(connectTimeout.toMillis())); } @Test void configureUriWithNoScheme() { this.contextRunner.withPropertyValues("spring.elasticsearch.uris=localhost:9876").run((context) -> { - RestClient client = context.getBean(org.elasticsearch.client.RestHighLevelClient.class).getLowLevelClient(); + RestClient client = context.getBean(RestClient.class); assertThat(client.getNodes().stream().map(Node::getHost).map(HttpHost::toString)) .containsExactly("http://localhost:9876"); }); @@ -151,7 +160,7 @@ void configureUriWithNoScheme() { @Test void configureUriWithUsernameOnly() { this.contextRunner.withPropertyValues("spring.elasticsearch.uris=http://user@localhost:9200").run((context) -> { - RestClient client = context.getBean(org.elasticsearch.client.RestHighLevelClient.class).getLowLevelClient(); + RestClient client = context.getBean(RestClient.class); assertThat(client.getNodes().stream().map(Node::getHost).map(HttpHost::toString)) .containsExactly("http://localhost:9200"); assertThat(client) @@ -168,8 +177,7 @@ void configureUriWithUsernameOnly() { void configureUriWithUsernameAndEmptyPassword() { this.contextRunner.withPropertyValues("spring.elasticsearch.uris=http://user:@localhost:9200") .run((context) -> { - RestClient client = context.getBean(org.elasticsearch.client.RestHighLevelClient.class) - .getLowLevelClient(); + RestClient client = context.getBean(RestClient.class); assertThat(client.getNodes().stream().map(Node::getHost).map(HttpHost::toString)) .containsExactly("http://localhost:9200"); assertThat(client) @@ -190,8 +198,7 @@ void configureUriWithUsernameAndPasswordWhenUsernameAndPasswordPropertiesSet() { .withPropertyValues("spring.elasticsearch.uris=http://user:password@localhost:9200,localhost:9201", "spring.elasticsearch.username=admin", "spring.elasticsearch.password=admin") .run((context) -> { - RestClient client = context.getBean(org.elasticsearch.client.RestHighLevelClient.class) - .getLowLevelClient(); + RestClient client = context.getBean(RestClient.class); assertThat(client.getNodes().stream().map(Node::getHost).map(HttpHost::toString)) .containsExactly("http://localhost:9200", "http://localhost:9201"); assertThat(client) @@ -213,7 +220,7 @@ void configureUriWithUsernameAndPasswordWhenUsernameAndPasswordPropertiesSet() { @Test void configureWithCustomPathPrefix() { this.contextRunner.withPropertyValues("spring.elasticsearch.path-prefix=/some/prefix").run((context) -> { - RestClient client = context.getBean(org.elasticsearch.client.RestHighLevelClient.class).getLowLevelClient(); + RestClient client = context.getBean(RestClient.class); assertThat(client).extracting("pathPrefix").isEqualTo("/some/prefix"); }); } @@ -222,19 +229,21 @@ void configureWithCustomPathPrefix() { void configureWithoutSnifferLibraryShouldNotCreateSniffer() { this.contextRunner.withClassLoader(new FilteredClassLoader("org.elasticsearch.client.sniff")) .run((context) -> assertThat(context).hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class) - .doesNotHaveBean(Sniffer.class)); + .hasSingleBean(RestClient.class).doesNotHaveBean(Sniffer.class)); } @Test - void configureShouldCreateSnifferUsingRestHighLevelClient() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(Sniffer.class); - assertThat(context.getBean(Sniffer.class)).hasFieldOrPropertyWithValue("restClient", - context.getBean(org.elasticsearch.client.RestHighLevelClient.class).getLowLevelClient()); - // Validate shutdown order as the sniffer must be shutdown before the client - assertThat(context.getBeanFactory().getDependentBeans("elasticsearchRestHighLevelClient")) - .contains("elasticsearchSniffer"); - }); + void configureShouldCreateSnifferUsingRestClient() { + this.contextRunner.withClassLoader(new FilteredClassLoader(org.elasticsearch.client.RestHighLevelClient.class)) + .run((context) -> { + assertThat(context).hasSingleBean(Sniffer.class); + assertThat(context.getBean(Sniffer.class)).hasFieldOrPropertyWithValue("restClient", + context.getBean(RestClient.class)); + // Validate shutdown order as the sniffer must be shutdown before the + // client + assertThat(context.getBeanFactory().getDependentBeans("elasticsearchRestClient")) + .contains("elasticsearchSniffer"); + }); } @Test @@ -299,7 +308,7 @@ org.elasticsearch.client.RestHighLevelClient customRestHighLevelClient(RestClien } @Configuration(proxyBeanMethods = false) - static class TwoCustomRestHighLevelClientConfiguration { + static class CustomRestHighLevelClientWithRestClientConfiguration { @Bean org.elasticsearch.client.RestHighLevelClient customRestHighLevelClient(RestClientBuilder builder) { @@ -307,7 +316,22 @@ org.elasticsearch.client.RestHighLevelClient customRestHighLevelClient(RestClien } @Bean - org.elasticsearch.client.RestHighLevelClient customoRestHighLevelClient1(RestClientBuilder builder) { + RestClient customRestClient(org.elasticsearch.client.RestHighLevelClient restHighLevelClient) { + return restHighLevelClient.getLowLevelClient(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class TwoCustomRestHighLevelClientsConfiguration { + + @Bean + org.elasticsearch.client.RestHighLevelClient customRestHighLevelClient(RestClientBuilder builder) { + return new org.elasticsearch.client.RestHighLevelClient(builder); + } + + @Bean + org.elasticsearch.client.RestHighLevelClient anotherCustomRestHighLevelClient(RestClientBuilder builder) { return new org.elasticsearch.client.RestHighLevelClient(builder); } @@ -323,4 +347,19 @@ RestClient customRestClient(RestClientBuilder builder) { } + @Configuration(proxyBeanMethods = false) + static class TwoCustomRestClientConfiguration { + + @Bean + RestClient customRestClient(RestClientBuilder builder) { + return builder.build(); + } + + @Bean + RestClient customRestClient1(RestClientBuilder builder) { + return builder.build(); + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/gson/GsonAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/gson/GsonAutoConfigurationTests.java index 772f36879ebb..6e1f0e0aa5f6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/gson/GsonAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/gson/GsonAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -29,6 +29,7 @@ import com.google.gson.GsonBuilder; import com.google.gson.LongSerializationPolicy; import org.junit.jupiter.api.Test; +import org.skyscreamer.jsonassert.JSONAssert; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -150,7 +151,7 @@ void additionalGsonBuilderCustomization() { void customGsonBuilder() { this.contextRunner.withUserConfiguration(GsonBuilderConfig.class).run((context) -> { Gson gson = context.getBean(Gson.class); - assertThat(gson.toJson(new DataObject())).isEqualTo("{\"data\":1,\"owner\":null}"); + JSONAssert.assertEquals("{\"data\":1,\"owner\":null}", gson.toJson(new DataObject()), true); }); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java index fb4f3880cf68..73d7a39cc8c4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -17,6 +17,7 @@ package org.springframework.boot.autoconfigure.security.oauth2.resource.reactive; import java.io.IOException; +import java.time.Duration; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -83,6 +84,8 @@ class ReactiveOAuth2ResourceServerAutoConfigurationTests { private MockWebServer server; + private static final Duration TIMEOUT = Duration.ofSeconds(5); + private static final String JWK_SET = "{\"keys\":[{\"kty\":\"RSA\",\"e\":\"AQAB\",\"use\":\"sig\"," + "\"kid\":\"one\",\"n\":\"oXJ8OyOv_eRnce4akdanR4KYRfnC2zLV4uYNQpcFn6oHL0dj7D6kxQmsXoYgJV8ZVDn71KGm" + "uLvolxsDncc2UrhyMBY6DVQVgMSVYaPCTgW76iYEKGgzTEw5IBRQL9w3SRJWd3VJTZZQjkXef48Ocz06PGF3lhbz4t5UEZtd" @@ -148,7 +151,7 @@ void autoConfigurationShouldConfigureResourceServerUsingOidcIssuerUri() throws I .getBean(SupplierReactiveJwtDecoder.class); Mono reactiveJwtDecoderSupplier = (Mono) ReflectionTestUtils .getField(supplierReactiveJwtDecoder, "jwtDecoderMono"); - ReactiveJwtDecoder reactiveJwtDecoder = reactiveJwtDecoderSupplier.block(); + ReactiveJwtDecoder reactiveJwtDecoder = reactiveJwtDecoderSupplier.block(TIMEOUT); }); // The last request is to the JWK Set endpoint to look up the algorithm assertThat(this.server.getRequestCount()).isEqualTo(1); @@ -171,7 +174,7 @@ void autoConfigurationShouldConfigureResourceServerUsingOidcRfc8414IssuerUri() t .getBean(SupplierReactiveJwtDecoder.class); Mono reactiveJwtDecoderSupplier = (Mono) ReflectionTestUtils .getField(supplierReactiveJwtDecoder, "jwtDecoderMono"); - ReactiveJwtDecoder reactiveJwtDecoder = reactiveJwtDecoderSupplier.block(); + ReactiveJwtDecoder reactiveJwtDecoder = reactiveJwtDecoderSupplier.block(TIMEOUT); }); // The last request is to the JWK Set endpoint to look up the algorithm assertThat(this.server.getRequestCount()).isEqualTo(2); @@ -194,7 +197,7 @@ void autoConfigurationShouldConfigureResourceServerUsingOAuthIssuerUri() throws .getBean(SupplierReactiveJwtDecoder.class); Mono reactiveJwtDecoderSupplier = (Mono) ReflectionTestUtils .getField(supplierReactiveJwtDecoder, "jwtDecoderMono"); - ReactiveJwtDecoder reactiveJwtDecoder = reactiveJwtDecoderSupplier.block(); + ReactiveJwtDecoder reactiveJwtDecoder = reactiveJwtDecoderSupplier.block(TIMEOUT); }); // The last request is to the JWK Set endpoint to look up the algorithm assertThat(this.server.getRequestCount()).isEqualTo(3); @@ -395,7 +398,7 @@ private void assertFilterConfiguredWithJwtAuthenticationManager(AssertableReacti .filter((f) -> f instanceof AuthenticationWebFilter).findFirst().orElse(null); ReactiveAuthenticationManagerResolver authenticationManagerResolver = (ReactiveAuthenticationManagerResolver) ReflectionTestUtils .getField(webFilter, "authenticationManagerResolver"); - Object authenticationManager = authenticationManagerResolver.resolve(null).block(); + Object authenticationManager = authenticationManagerResolver.resolve(null).block(TIMEOUT); assertThat(authenticationManager).isInstanceOf(JwtReactiveAuthenticationManager.class); } @@ -408,7 +411,7 @@ private void assertFilterConfiguredWithOpaqueTokenAuthenticationManager( .filter((f) -> f instanceof AuthenticationWebFilter).findFirst().orElse(null); ReactiveAuthenticationManagerResolver authenticationManagerResolver = (ReactiveAuthenticationManagerResolver) ReflectionTestUtils .getField(webFilter, "authenticationManagerResolver"); - Object authenticationManager = authenticationManagerResolver.resolve(null).block(); + Object authenticationManager = authenticationManagerResolver.resolve(null).block(TIMEOUT); assertThat(authenticationManager).isInstanceOf(OpaqueTokenReactiveAuthenticationManager.class); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java index b38f8fb64c67..81d92c4bd03b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java @@ -120,12 +120,12 @@ void autoConfigurationWhenSignRequestsFalseAndNoSigningCredentialsShouldNotThrow } @Test - void autoconfigurationShouldQueryIdentityProviderMetadataWhenMetadataUrlIsPresent() throws Exception { + void autoconfigurationShouldQueryAssertingPartyMetadataWhenMetadataUrlIsPresent() throws Exception { try (MockWebServer server = new MockWebServer()) { server.start(); String metadataUrl = server.url("").toString(); setupMockResponse(server, new ClassPathResource("saml/idp-metadata")); - this.contextRunner.withPropertyValues(PREFIX + ".foo.identityprovider.metadata-uri=" + metadataUrl) + this.contextRunner.withPropertyValues(PREFIX + ".foo.asserting-party.metadata-uri=" + metadataUrl) .run((context) -> { assertThat(context).hasSingleBean(RelyingPartyRegistrationRepository.class); assertThat(server.getRequestCount()).isEqualTo(1); @@ -139,7 +139,7 @@ void autoconfigurationShouldUseBindingFromMetadataUrlIfPresent() throws Exceptio server.start(); String metadataUrl = server.url("").toString(); setupMockResponse(server, new ClassPathResource("saml/idp-metadata")); - this.contextRunner.withPropertyValues(PREFIX + ".foo.identityprovider.metadata-uri=" + metadataUrl) + this.contextRunner.withPropertyValues(PREFIX + ".foo.asserting-party.metadata-uri=" + metadataUrl) .run((context) -> { RelyingPartyRegistrationRepository repository = context .getBean(RelyingPartyRegistrationRepository.class); @@ -156,8 +156,8 @@ void autoconfigurationWhenMetadataUrlAndPropertyPresentShouldUseBindingFromPrope server.start(); String metadataUrl = server.url("").toString(); setupMockResponse(server, new ClassPathResource("saml/idp-metadata")); - this.contextRunner.withPropertyValues(PREFIX + ".foo.identityprovider.metadata-uri=" + metadataUrl, - PREFIX + ".foo.identityprovider.singlesignon.binding=redirect").run((context) -> { + this.contextRunner.withPropertyValues(PREFIX + ".foo.asserting-party.metadata-uri=" + metadataUrl, + PREFIX + ".foo.asserting-party.singlesignon.binding=redirect").run((context) -> { RelyingPartyRegistrationRepository repository = context .getBean(RelyingPartyRegistrationRepository.class); RelyingPartyRegistration registration = repository.findByRegistrationId("foo"); @@ -215,19 +215,19 @@ void samlLoginShouldShouldBeConditionalOnSecurityWebFilterClass() { private String[] getPropertyValuesWithoutSigningCredentials(boolean signRequests) { return new String[] { PREFIX - + ".foo.identityprovider.singlesignon.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php", - PREFIX + ".foo.identityprovider.singlesignon.binding=post", - PREFIX + ".foo.identityprovider.singlesignon.sign-request=" + signRequests, - PREFIX + ".foo.identityprovider.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", - PREFIX + ".foo.identityprovider.verification.credentials[0].certificate-location=classpath:saml/certificate-location" }; + + ".foo.asserting-party.singlesignon.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php", + PREFIX + ".foo.asserting-party.singlesignon.binding=post", + PREFIX + ".foo.asserting-party.singlesignon.sign-request=" + signRequests, + PREFIX + ".foo.asserting-party.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", + PREFIX + ".foo.asserting-party.verification.credentials[0].certificate-location=classpath:saml/certificate-location" }; } private String[] getPropertyValuesWithoutSsoBinding() { return new String[] { PREFIX - + ".foo.identityprovider.singlesignon.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php", - PREFIX + ".foo.identityprovider.singlesignon.sign-request=false", - PREFIX + ".foo.identityprovider.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", - PREFIX + ".foo.identityprovider.verification.credentials[0].certificate-location=classpath:saml/certificate-location" }; + + ".foo.asserting-party.singlesignon.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php", + PREFIX + ".foo.asserting-party.singlesignon.sign-request=false", + PREFIX + ".foo.asserting-party.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", + PREFIX + ".foo.asserting-party.verification.credentials[0].certificate-location=classpath:saml/certificate-location" }; } private String[] getPropertyValues() { @@ -236,11 +236,11 @@ private String[] getPropertyValues() { PREFIX + ".foo.signing.credentials[0].certificate-location=classpath:saml/certificate-location", PREFIX + ".foo.decryption.credentials[0].private-key-location=classpath:saml/private-key-location", PREFIX + ".foo.decryption.credentials[0].certificate-location=classpath:saml/certificate-location", - PREFIX + ".foo.identityprovider.singlesignon.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php", - PREFIX + ".foo.identityprovider.singlesignon.binding=post", - PREFIX + ".foo.identityprovider.singlesignon.sign-request=false", - PREFIX + ".foo.identityprovider.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", - PREFIX + ".foo.identityprovider.verification.credentials[0].certificate-location=classpath:saml/certificate-location", + PREFIX + ".foo.asserting-party.singlesignon.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php", + PREFIX + ".foo.asserting-party.singlesignon.binding=post", + PREFIX + ".foo.asserting-party.singlesignon.sign-request=false", + PREFIX + ".foo.asserting-party.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", + PREFIX + ".foo.asserting-party.verification.credentials[0].certificate-location=classpath:saml/certificate-location", PREFIX + ".foo.entity-id={baseUrl}/saml2/foo-entity-id", PREFIX + ".foo.acs.location={baseUrl}/login/saml2/foo-entity-id", PREFIX + ".foo.acs.binding=redirect" }; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java index 04f16e9f9618..9dd726543895 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -41,36 +41,29 @@ class Saml2RelyingPartyPropertiesTests { @Test void customizeSsoUrl() { - bind("spring.security.saml2.relyingparty.registration.simplesamlphp.identity-provider.single-sign-on.url", + bind("spring.security.saml2.relyingparty.registration.simplesamlphp.asserting-party.single-sign-on.url", "https://simplesaml-for-spring-saml/SSOService.php"); assertThat( - this.properties.getRegistration().get("simplesamlphp").getIdentityprovider().getSinglesignon().getUrl()) + this.properties.getRegistration().get("simplesamlphp").getAssertingParty().getSinglesignon().getUrl()) .isEqualTo("https://simplesaml-for-spring-saml/SSOService.php"); } @Test void customizeSsoBinding() { - bind("spring.security.saml2.relyingparty.registration.simplesamlphp.identity-provider.single-sign-on.binding", + bind("spring.security.saml2.relyingparty.registration.simplesamlphp.asserting-party.single-sign-on.binding", "post"); - assertThat(this.properties.getRegistration().get("simplesamlphp").getIdentityprovider().getSinglesignon() + assertThat(this.properties.getRegistration().get("simplesamlphp").getAssertingParty().getSinglesignon() .getBinding()).isEqualTo(Saml2MessageBinding.POST); } @Test void customizeSsoSignRequests() { - bind("spring.security.saml2.relyingparty.registration.simplesamlphp.identity-provider.single-sign-on.sign-request", + bind("spring.security.saml2.relyingparty.registration.simplesamlphp.asserting-party.single-sign-on.sign-request", "false"); - assertThat(this.properties.getRegistration().get("simplesamlphp").getIdentityprovider().getSinglesignon() + assertThat(this.properties.getRegistration().get("simplesamlphp").getAssertingParty().getSinglesignon() .isSignRequest()).isEqualTo(false); } - @Test - void customizeSsoSignRequestsIsTrueByDefault() { - this.properties.getRegistration().put("simplesamlphp", new Saml2RelyingPartyProperties.Registration()); - assertThat(this.properties.getRegistration().get("simplesamlphp").getIdentityprovider().getSinglesignon() - .isSignRequest()).isEqualTo(true); - } - @Test void customizeRelyingPartyEntityId() { bind("spring.security.saml2.relyingparty.registration.simplesamlphp.entity-id", @@ -86,13 +79,20 @@ void customizeRelyingPartyEntityIdDefaultsToServiceProviderMetadata() { } @Test - void customizeIdentityProviderMetadataUri() { - bind("spring.security.saml2.relyingparty.registration.simplesamlphp.identityprovider.metadata-uri", + void customizeAssertingPartyMetadataUri() { + bind("spring.security.saml2.relyingparty.registration.simplesamlphp.asserting-party.metadata-uri", "https://idp.example.org/metadata"); - assertThat(this.properties.getRegistration().get("simplesamlphp").getIdentityprovider().getMetadataUri()) + assertThat(this.properties.getRegistration().get("simplesamlphp").getAssertingParty().getMetadataUri()) .isEqualTo("https://idp.example.org/metadata"); } + @Test + void customizeSsoSignRequestsIsTrueByDefault() { + this.properties.getRegistration().put("simplesamlphp", new Saml2RelyingPartyProperties.Registration()); + assertThat(this.properties.getRegistration().get("simplesamlphp").getAssertingParty().getSinglesignon() + .isSignRequest()).isEqualTo(true); + } + private void bind(String name, String value) { bind(Collections.singletonMap(name, value)); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java index 6e81c0217309..8f7ef62b92bd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java @@ -97,8 +97,7 @@ void defaultMediaTypes() { MediaType.APPLICATION_ATOM_XML, new MediaType("application", "javascript"), new MediaType("application", "ecmascript"), new MediaType("text", "javascript"), new MediaType("text", "ecmascript"), MediaType.APPLICATION_JSON, - new MediaType("text", "css"), MediaType.TEXT_PLAIN, MediaType.TEXT_EVENT_STREAM) - .satisfies(System.out::println)); + new MediaType("text", "css"), MediaType.TEXT_PLAIN, MediaType.TEXT_EVENT_STREAM)); } @Test diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientAutoConfigurationTests.java index 9059dd3b0666..509effe61c37 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientAutoConfigurationTests.java @@ -16,12 +16,7 @@ package org.springframework.boot.autoconfigure.web.reactive.function.client; -import java.net.URI; -import java.time.Duration; - import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -29,20 +24,13 @@ import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.client.reactive.ClientHttpConnector; -import org.springframework.http.client.reactive.ClientHttpResponse; import org.springframework.http.codec.CodecConfigurer; import org.springframework.web.reactive.function.client.WebClient; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.then; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; /** * Tests for {@link WebClientAutoConfiguration} @@ -88,26 +76,9 @@ void webClientShouldApplyCustomizers() { @Test void shouldGetPrototypeScopedBean() { this.contextRunner.withUserConfiguration(WebClientCustomizerConfig.class).run((context) -> { - ClientHttpResponse response = mock(ClientHttpResponse.class); - given(response.getBody()).willReturn(Flux.empty()); - given(response.getHeaders()).willReturn(new HttpHeaders()); - ClientHttpConnector firstConnector = mock(ClientHttpConnector.class); - given(firstConnector.connect(any(), any(), any())).willReturn(Mono.just(response)); WebClient.Builder firstBuilder = context.getBean(WebClient.Builder.class); - firstBuilder.clientConnector(firstConnector).baseUrl("https://first.example.org"); - ClientHttpConnector secondConnector = mock(ClientHttpConnector.class); - given(secondConnector.connect(any(), any(), any())).willReturn(Mono.just(response)); WebClient.Builder secondBuilder = context.getBean(WebClient.Builder.class); - secondBuilder.clientConnector(secondConnector).baseUrl("https://second.example.org"); assertThat(firstBuilder).isNotEqualTo(secondBuilder); - firstBuilder.build().get().uri("/foo").retrieve().toBodilessEntity().block(Duration.ofSeconds(30)); - secondBuilder.build().get().uri("/foo").retrieve().toBodilessEntity().block(Duration.ofSeconds(30)); - then(firstConnector).should().connect(eq(HttpMethod.GET), eq(URI.create("https://first.example.org/foo")), - any()); - then(secondConnector).should().connect(eq(HttpMethod.GET), eq(URI.create("https://second.example.org/foo")), - any()); - WebClientCustomizer customizer = context.getBean("webClientCustomizer", WebClientCustomizer.class); - then(customizer).should(times(2)).customize(any(WebClient.Builder.class)); }); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java index 0d3b6dff4fd6..59cbd17916a3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java @@ -26,7 +26,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/RemappedErrorViewIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/RemappedErrorViewIntegrationTests.java index 72ff200d3cf3..b5e25e65c007 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/RemappedErrorViewIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/RemappedErrorViewIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -27,10 +27,10 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.server.ErrorPage; import org.springframework.boot.web.server.ErrorPageRegistrar; import org.springframework.boot.web.server.ErrorPageRegistry; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.stereotype.Controller; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketMessagingAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketMessagingAutoConfigurationTests.java index 7043d05f3912..21019ab69328 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketMessagingAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketMessagingAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -30,6 +30,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.skyscreamer.jsonassert.JSONAssert; import org.springframework.boot.LazyInitializationBeanFactoryPostProcessor; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -38,7 +39,6 @@ import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.annotation.Bean; @@ -101,7 +101,7 @@ void tearDown() { @Test void basicMessagingWithJsonResponse() throws Throwable { Object result = performStompSubscription("/app/json"); - assertThat(new String((byte[]) result)).isEqualTo(String.format("{%n \"foo\" : 5,%n \"bar\" : \"baz\"%n}")); + JSONAssert.assertEquals("{\"foo\" : 5,\"bar\" : \"baz\"}", new String((byte[]) result), true); } @Test @@ -146,7 +146,6 @@ private List getDefaultConverters() { private Object performStompSubscription(String topic) throws Throwable { TestPropertyValues.of("server.port:0", "spring.jackson.serialization.indent-output:true").applyTo(this.context); this.context.register(WebSocketMessagingConfiguration.class); - new ServerPortInfoApplicationContextInitializer().initialize(this.context); this.context.refresh(); WebSocketStompClient stompClient = new WebSocketStompClient(this.sockJsClient); final AtomicReference failure = new AtomicReference<>(); @@ -193,8 +192,7 @@ public void handleTransportError(StompSession session, Throwable exception) { }; stompClient.setMessageConverter(new SimpleMessageConverter()); - stompClient.connect("ws://localhost:{port}/messaging", handler, - this.context.getEnvironment().getProperty("local.server.port")); + stompClient.connect("ws://localhost:{port}/messaging", handler, this.context.getWebServer().getPort()); if (!latch.await(30, TimeUnit.SECONDS)) { if (failure.get() != null) { diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index d4fb5389fa18..579019537e05 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -24,7 +24,7 @@ bom { ] } } - library("AppEngine SDK", "1.9.95") { + library("AppEngine SDK", "1.9.96") { group("com.google.appengine") { modules = [ "appengine-api-1.0-sdk" @@ -79,7 +79,7 @@ bom { ] } } - library("Byte Buddy", "1.12.8") { + library("Byte Buddy", "1.12.9") { group("net.bytebuddy") { modules = [ "byte-buddy", @@ -216,7 +216,7 @@ bom { ] } } - library("Elasticsearch", "7.17.1") { + library("Elasticsearch", "7.17.2") { group("org.elasticsearch") { modules = [ "elasticsearch" @@ -254,7 +254,7 @@ bom { ] } } - library("Flyway", "8.5.4") { + library("Flyway", "8.5.8") { group("org.flywaydb") { modules = [ "flyway-core", @@ -323,7 +323,7 @@ bom { ] } } - library("H2", "2.1.210") { + library("H2", "2.1.212") { group("com.h2database") { modules = [ "h2" @@ -355,7 +355,7 @@ bom { ] } } - library("Hibernate", "5.6.7.Final") { + library("Hibernate", "5.6.8.Final") { group("org.hibernate") { modules = [ "hibernate-c3p0", @@ -463,7 +463,7 @@ bom { ] } } - library("Jackson Bom", "2.13.2") { + library("Jackson Bom", "2.13.2.1") { group("com.fasterxml.jackson") { imports = [ "jackson-bom" @@ -795,7 +795,7 @@ bom { ] } } - library("Kotlin Coroutines", "1.6.0") { + library("Kotlin Coroutines", "1.6.1") { group("org.jetbrains.kotlinx") { imports = [ "kotlinx-coroutines-bom" @@ -809,7 +809,7 @@ bom { ] } } - library("Liquibase", "4.9.0") { + library("Liquibase", "4.9.1") { group("org.liquibase") { modules = [ "liquibase-cdi", @@ -836,14 +836,14 @@ bom { ] } } - library("Lombok", "1.18.22") { + library("Lombok", "1.18.24") { group("org.projectlombok") { modules = [ "lombok" ] } } - library("MariaDB", "3.0.3") { + library("MariaDB", "3.0.4") { group("org.mariadb.jdbc") { modules = [ "mariadb-java-client" @@ -864,7 +864,7 @@ bom { ] } } - library("Maven Clean Plugin", "3.1.0") { + library("Maven Clean Plugin", "3.2.0") { group("org.apache.maven.plugins") { plugins = [ "maven-clean-plugin" @@ -948,7 +948,7 @@ bom { ] } } - library("Maven Shade Plugin", "3.2.4") { + library("Maven Shade Plugin", "3.3.0") { group("org.apache.maven.plugins") { plugins = [ "maven-shade-plugin" @@ -976,7 +976,7 @@ bom { ] } } - library("Micrometer", "2.0.0-SNAPSHOT") { + library("Micrometer", "1.10.0-SNAPSHOT") { group("io.micrometer") { modules = [ "micrometer-registry-stackdriver" { @@ -990,28 +990,26 @@ bom { } library("Micrometer Tracing", "1.0.0-SNAPSHOT") { group("io.micrometer") { - modules = [ - "micrometer-tracing-api" + imports = [ + "micrometer-tracing-bom" ] } } - library("MIMEPull", "1.9.15") { + library("MIMEPull", "1.10.0") { group("org.jvnet.mimepull") { modules = [ "mimepull" ] } } - library("Mockito", "4.4.0") { + library("Mockito", "4.5.0") { group("org.mockito") { - modules = [ - "mockito-core", - "mockito-inline", - "mockito-junit-jupiter" + imports = [ + "mockito-bom" ] } } - library("MongoDB", "4.5.1") { + library("MongoDB", "4.6.0") { group("org.mongodb") { modules = [ "bson", @@ -1052,7 +1050,7 @@ bom { ] } } - library("Netty", "4.1.75.Final") { + library("Netty", "4.1.76.Final") { group("io.netty") { imports = [ "netty-bom" @@ -1074,6 +1072,13 @@ bom { ] } } + library("OpenTelemetry", "1.12.0") { + group("io.opentelemetry") { + imports = [ + "opentelemetry-bom" + ] + } + } library("Oracle Database", "21.5.0.0") { group("com.oracle.database.jdbc") { imports = [ @@ -1141,7 +1146,7 @@ bom { ] } } - library("Reactor Bom", "2020.0.17") { + library("Reactor Bom", "2020.0.18") { group("io.projectreactor") { imports = [ "reactor-bom" @@ -1161,7 +1166,7 @@ bom { ] } } - library("RSocket", "1.1.1") { + library("RSocket", "1.1.2") { group("io.rsocket") { imports = [ "rsocket-bom" @@ -1359,21 +1364,21 @@ bom { ] } } - library("Spring Data Bom", "2022.0.0-M3") { + library("Spring Data Bom", "2022.0.0-SNAPSHOT") { group("org.springframework.data") { imports = [ "spring-data-bom" ] } } - library("Spring Framework", "6.0.0-M3") { + library("Spring Framework", "6.0.0-SNAPSHOT") { group("org.springframework") { imports = [ "spring-framework-bom" ] } } - library("Spring HATEOAS", "2.0.0-M2") { + library("Spring HATEOAS", "2.0.0-SNAPSHOT") { group("org.springframework.hateoas") { modules = [ "spring-hateoas" @@ -1387,7 +1392,7 @@ bom { ] } } - library("Spring Kafka", "3.0.0-M3") { + library("Spring Kafka", "3.0.0-SNAPSHOT") { group("org.springframework.kafka") { modules = [ "spring-kafka", @@ -1418,21 +1423,21 @@ bom { ] } } - library("Spring Retry", "1.3.2") { + library("Spring Retry", "1.3.3") { group("org.springframework.retry") { modules = [ "spring-retry" ] } } - library("Spring Security", "6.0.0-M3") { + library("Spring Security", "6.0.0-SNAPSHOT") { group("org.springframework.security") { imports = [ "spring-security-bom" ] } } - library("Spring Session Bom", "2022.0.0-M1") { + library("Spring Session Bom", "2022.0.0-SNAPSHOT") { group("org.springframework.session") { imports = [ "spring-session-bom" @@ -1524,7 +1529,7 @@ bom { ] } } - library("Undertow", "2.2.16.Final") { + library("Undertow", "2.2.17.Final") { group("io.undertow") { modules = [ "undertow-core", @@ -1579,6 +1584,13 @@ bom { ] } } + library("Zipkin", "2.16.3") { + group("io.zipkin.reporter2") { + modules = [ + "zipkin-sender-urlconnection" + ] + } + } } generateMetadataFileForMavenPublication { diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java index 1f0a38652c15..26c28ceacec5 100755 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java @@ -18,6 +18,7 @@ import java.io.IOException; import java.io.InputStream; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Properties; @@ -74,7 +75,7 @@ public class DevToolsPropertyDefaultsPostProcessor implements EnvironmentPostPro for (String name : properties.stringPropertyNames()) { map.put(name, properties.getProperty(name)); } - PROPERTIES = map; + PROPERTIES = Collections.unmodifiableMap(map); } @Override diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java index b32a603d3fb8..7e4e6832c7eb 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-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. @@ -42,6 +42,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpRequestFactory; @@ -108,7 +109,7 @@ private void performUpload(ClassLoaderFiles classLoaderFiles, byte[] bytes) thro headers.setContentLength(bytes.length); FileCopyUtils.copy(bytes, request.getBody()); ClientHttpResponse response = request.execute(); - HttpStatus statusCode = response.getStatusCode(); + HttpStatusCode statusCode = response.getStatusCode(); Assert.state(statusCode == HttpStatus.OK, () -> "Unexpected " + statusCode + " response uploading class files"); logUpload(classLoaderFiles); diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/Restarter.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/Restarter.java index 0981ce24a288..9f0f89e83f98 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/Restarter.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/Restarter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -350,17 +350,6 @@ private void clearAnnotationUtilsCache() throws Exception { } } - private void clear(String className, String fieldName) { - try { - clear(Class.forName(className), fieldName); - } - catch (Exception ex) { - if (this.logger.isDebugEnabled()) { - this.logger.debug("Unable to clear field " + className + " " + fieldName, ex); - } - } - } - private void clear(Class type, String fieldName) throws Exception { try { Field field = type.getDeclaredField(fieldName); diff --git a/spring-boot-project/spring-boot-docs/build.gradle b/spring-boot-project/spring-boot-docs/build.gradle index ba758eb2d812..40941a19638b 100644 --- a/spring-boot-project/spring-boot-docs/build.gradle +++ b/spring-boot-project/spring-boot-docs/build.gradle @@ -77,7 +77,6 @@ dependencies { implementation("ch.qos.logback:logback-classic") implementation("com.zaxxer:HikariCP") implementation("io.micrometer:micrometer-core") - implementation("io.micrometer:micrometer-binders") implementation("io.micrometer:micrometer-registry-graphite") implementation("io.micrometer:micrometer-registry-jmx") implementation("io.projectreactor.netty:reactor-netty-http") diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/metrics.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/metrics.adoc index bb175b6d64bd..848c00341dce 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/metrics.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/metrics.adoc @@ -589,9 +589,7 @@ If you are exporting metrics to https://www.wavefront.com/[Wavefront] directly, ---- management: wavefront: - metrics: - export: - api-token: "YOUR_API_TOKEN" + api-token: "YOUR_API_TOKEN" ---- Alternatively, you can use a Wavefront sidecar or an internal proxy in your environment to forward metrics data to the Wavefront API host: @@ -600,9 +598,7 @@ Alternatively, you can use a Wavefront sidecar or an internal proxy in your envi ---- management: wavefront: - metrics: - export: - uri: "proxy://localhost:2878" + uri: "proxy://localhost:2878" ---- NOTE: If you publish metrics to a Wavefront proxy (as described in https://docs.wavefront.com/proxies_installing.html[the Wavefront documentation]), the host must be in the `proxy://HOST:PORT` format. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/container-images/dockerfiles.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/container-images/dockerfiles.adoc index c3fb26ec168c..6cc5e18cbd3f 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/container-images/dockerfiles.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/container-images/dockerfiles.adoc @@ -32,13 +32,13 @@ Here is an example of a Dockerfile using `jarmode`. [source,dockerfile,indent=0,subs="verbatim"] ---- -FROM adoptopenjdk:11-jre-hotspot as builder +FROM eclipse-temurin:11-jre as builder WORKDIR application ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} application.jar RUN java -Djarmode=layertools -jar application.jar extract -FROM adoptopenjdk:11-jre-hotspot +FROM eclipse-temurin:11-jre WORKDIR application COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/data/nosql.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/data/nosql.adoc index 56823d5325d1..10f8d029ed9b 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/data/nosql.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/data/nosql.adoc @@ -252,9 +252,8 @@ Spring Boot provides a dedicated "`Starter`", `spring-boot-starter-data-elastics [[data.nosql.elasticsearch.connecting-using-rest]] ==== Connecting to Elasticsearch using REST clients -Elasticsearch ships https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/index.html[two different REST clients] that you can use to query a cluster: the "Low Level" client and the "High Level" client. -Spring Boot provides support for the "High Level" client, which ships with `org.elasticsearch.client:elasticsearch-rest-high-level-client`. -Additionally, Spring Boot provides support for a reactive client, based on Spring Framework's `WebClient`, that ships with `org.springframework.data:spring-data-elasticsearch`. +Elasticsearch ships https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/index.html[two different REST clients] that you can use to query a cluster: the low-level client from the `org.elasticsearch.client:elasticsearch-rest-client` module and the high-level client from the `org.elasticsearch.client:elasticsearch-high-level-client` module. +Additionally, Spring Boot provides support for a reactive client, based on Spring Framework's `WebClient`, from the `org.springframework.data:spring-data-elasticsearch` module. By default, the clients will target `http://localhost:9200`. You can use `spring.elasticsearch.*` properties to further tune how the clients are configured, as shown in the following example: @@ -269,14 +268,16 @@ You can use `spring.elasticsearch.*` properties to further tune how the clients ---- [[data.nosql.elasticsearch.connecting-using-rest.restclient]] -===== Connecting to Elasticsearch using RestHighLevelClient -If you have `elasticsearch-rest-high-level-client` on the classpath, Spring Boot will auto-configure and register a `RestHighLevelClient` bean. -In addition to the properties described previously, to fine-tune the `RestHighLevelClient`, you can register an arbitrary number of beans that implement `RestClientBuilderCustomizer` for more advanced customizations. -To take full control over its registration, define a `RestClientBuilder` bean. +===== Connecting to Elasticsearch using RestClient +If you have `elasticsearch-rest-client` on the classpath, Spring Boot will auto-configure and register a `RestClient` bean. +If you have `elasticsearch-rest-high-level-client` on the classpath a `RestHighLevelClient` bean will be auto-configured as well. +Following Elasticsearch's deprecation of `RestHighLevelClient`, its auto-configuration is deprecated and will be removed in a future release. +In addition to the properties described previously, to fine-tune the `RestClient` and `RestHighLevelClient`, you can register an arbitrary number of beans that implement `RestClientBuilderCustomizer` for more advanced customizations. +To take full control over the clients' configuration, define a `RestClientBuilder` bean. -TIP: If your application needs access to a "Low Level" `RestClient`, you can get it by calling `client.getLowLevelClient()` on the auto-configured `RestHighLevelClient`. -Additionally, if `elasticsearch-rest-client-sniffer` is on the classpath, a `Sniffer` is auto-configured to automatically discover nodes from a running Elasticsearch cluster and set them on the `RestHighLevelClient` bean. + +Additionally, if `elasticsearch-rest-client-sniffer` is on the classpath, a `Sniffer` is auto-configured to automatically discover nodes from a running Elasticsearch cluster and set them on the `RestClient` bean. You can further tune how `Sniffer` is configured, as shown in the following example: [source,yaml,indent=0,subs="verbatim",configprops,configblocks] diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/spring-application.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/spring-application.adoc index c46dd1297944..a717c744636c 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/spring-application.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/spring-application.adoc @@ -352,6 +352,9 @@ include::code:MyApplication[] Also, the `ExitCodeGenerator` interface may be implemented by exceptions. When such an exception is encountered, Spring Boot returns the exit code provided by the implemented `getExitCode()` method. +If there is more than `ExitCodeGenerator`, the first non-zero exit code that is generated is used. +To control the order in which the generators are called, additionally implement the `org.springframework.core.Ordered` interface or use the `org.springframework.core.annotation.Order` annotation. + [[features.spring-application.admin]] diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/webserver.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/webserver.adoc index 97fb383a2fc3..2b3649b0b92c 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/webserver.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/webserver.adoc @@ -59,6 +59,13 @@ If you wish to use Jetty 10, which does support servlet 4.0, you can do so as sh org.springframework.boot spring-boot-starter-tomcat + + + + + org.springframework.boot + spring-boot-starter-jetty + org.eclipse.jetty.websocket @@ -70,11 +77,6 @@ If you wish to use Jetty 10, which does support servlet 4.0, you can do so as sh - - - org.springframework.boot - spring-boot-starter-jetty - ---- Note that along with excluding the Tomcat starter, a couple of Jetty9-specific dependencies also need to be excluded. @@ -181,7 +183,7 @@ You can configure this behavior by setting the configprop:server.compression.mim [[howto.webserver.configure-ssl]] === Configure SSL SSL can be configured declaratively by setting the various `+server.ssl.*+` properties, typically in `application.properties` or `application.yml`. -The following example shows setting SSL properties in `application.properties`: +The following example shows setting SSL properties using a Java KeyStore file: [source,yaml,indent=0,subs="verbatim",configprops,configblocks] ---- @@ -193,6 +195,19 @@ The following example shows setting SSL properties in `application.properties`: key-password: "another-secret" ---- +The following example shows setting SSL properties using PEM-encoded certificate and private key files: + +[source,yaml,indent=0,subs="verbatim",configprops,configblocks] +---- + server: + port: 8443 + ssl: + certificate: "classpath:my-cert.crt" + certificate-private-key: "classpath:my-cert.key" + trust-certificate: "classpath:ca-cert.crt" + key-store-password: "secret" +---- + See {spring-boot-module-code}/web/server/Ssl.java[`Ssl`] for details of all of the supported properties. Using configuration such as the preceding example means the application no longer supports a plain HTTP connector at port 8080. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/messaging/kafka.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/messaging/kafka.adoc index cb4c29f0fe51..8cfa6516a5e3 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/messaging/kafka.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/messaging/kafka.adoc @@ -61,7 +61,7 @@ The former can be configured using `spring.kafka.streams.application-id`, defaul The latter can be set globally or specifically overridden only for streams. Several additional properties are available using dedicated properties; other arbitrary Kafka properties can be set using the `spring.kafka.streams.properties` namespace. -See also <> for more information. +See also <> for more information. To use the factory bean, wire `StreamsBuilder` into your `@Bean` as shown in the following example: diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/spring-security.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/spring-security.adoc index a2370710e7b4..c7c95443d173 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/spring-security.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/spring-security.adoc @@ -262,7 +262,7 @@ You can register multiple relying parties under the `spring.security.saml2.relyi credentials: - private-key-location: "path-to-private-key" certificate-location: "path-to-certificate" - identityprovider: + asserting-party: verification: credentials: - certificate-location: "path-to-verification-cert" @@ -278,7 +278,7 @@ You can register multiple relying parties under the `spring.security.saml2.relyi credentials: - private-key-location: "path-to-private-key" certificate-location: "path-to-certificate" - identityprovider: + asserting-party: verification: credentials: - certificate-location: "path-to-other-verification-cert" diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/CustomCommandTagsProvider.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/CustomCommandTagsProvider.java index 17b85d18f08a..41014d0ab7c6 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/CustomCommandTagsProvider.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/CustomCommandTagsProvider.java @@ -17,8 +17,8 @@ package org.springframework.boot.docs.actuator.metrics.supported.mongodb.command; import com.mongodb.event.CommandEvent; -import io.micrometer.binder.mongodb.MongoCommandTagsProvider; import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.binder.mongodb.MongoCommandTagsProvider; class CustomCommandTagsProvider implements MongoCommandTagsProvider { diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/MyCommandTagsProviderConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/MyCommandTagsProviderConfiguration.java index c236945c7a33..ab651b4bf550 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/MyCommandTagsProviderConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/MyCommandTagsProviderConfiguration.java @@ -16,7 +16,7 @@ package org.springframework.boot.docs.actuator.metrics.supported.mongodb.command; -import io.micrometer.binder.mongodb.MongoCommandTagsProvider; +import io.micrometer.core.instrument.binder.mongodb.MongoCommandTagsProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/CustomConnectionPoolTagsProvider.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/CustomConnectionPoolTagsProvider.java index fa1dee5db1fd..24009433f4a4 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/CustomConnectionPoolTagsProvider.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/CustomConnectionPoolTagsProvider.java @@ -17,8 +17,8 @@ package org.springframework.boot.docs.actuator.metrics.supported.mongodb.connectionpool; import com.mongodb.event.ConnectionPoolCreatedEvent; -import io.micrometer.binder.mongodb.MongoConnectionPoolTagsProvider; import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.binder.mongodb.MongoConnectionPoolTagsProvider; public class CustomConnectionPoolTagsProvider implements MongoConnectionPoolTagsProvider { diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/MyConnectionPoolTagsProviderConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/MyConnectionPoolTagsProviderConfiguration.java index 0d6954fba2bb..8e4d09cbd03e 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/MyConnectionPoolTagsProviderConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/MyConnectionPoolTagsProviderConfiguration.java @@ -16,7 +16,7 @@ package org.springframework.boot.docs.actuator.metrics.supported.mongodb.connectionpool; -import io.micrometer.binder.mongodb.MongoConnectionPoolTagsProvider; +import io.micrometer.core.instrument.binder.mongodb.MongoConnectionPoolTagsProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringdataelasticsearch/MyDataElasticsearchTests.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringdataelasticsearch/MyDataElasticsearchTests.java index 42fc3f903caf..d2c0190773b3 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringdataelasticsearch/MyDataElasticsearchTests.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringdataelasticsearch/MyDataElasticsearchTests.java @@ -20,7 +20,7 @@ import org.springframework.boot.test.autoconfigure.data.elasticsearch.DataElasticsearchTest; @DataElasticsearchTest -public class MyDataElasticsearchTests { +class MyDataElasticsearchTests { @Autowired @SuppressWarnings("unused") diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.java index 9799fbfa4b90..d3a4f8c0620b 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.java @@ -23,7 +23,7 @@ import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.is; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.java index 520e6e3b1aa0..a88776943ea8 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -18,7 +18,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) public class MyWebIntegrationTests { diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/CustomCommandTagsProvider.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/CustomCommandTagsProvider.kt index 34ce16d9ff9c..b6353022db2d 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/CustomCommandTagsProvider.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/CustomCommandTagsProvider.kt @@ -17,8 +17,8 @@ package org.springframework.boot.docs.actuator.metrics.supported.mongodb.command import com.mongodb.event.CommandEvent -import io.micrometer.binder.mongodb.MongoCommandTagsProvider import io.micrometer.core.instrument.Tag +import io.micrometer.core.instrument.binder.mongodb.MongoCommandTagsProvider class CustomCommandTagsProvider : MongoCommandTagsProvider { diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/MyCommandTagsProviderConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/MyCommandTagsProviderConfiguration.kt index 796ad6dad5c6..91bcab1c9608 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/MyCommandTagsProviderConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/MyCommandTagsProviderConfiguration.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.actuator.metrics.supported.mongodb.command -import io.micrometer.binder.mongodb.MongoCommandTagsProvider +import io.micrometer.core.instrument.binder.mongodb.MongoCommandTagsProvider import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/CustomConnectionPoolTagsProvider.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/CustomConnectionPoolTagsProvider.kt index f05a1fdf56b4..8a766cd5c243 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/CustomConnectionPoolTagsProvider.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/CustomConnectionPoolTagsProvider.kt @@ -17,8 +17,8 @@ package org.springframework.boot.docs.actuator.metrics.supported.mongodb.connectionpool import com.mongodb.event.ConnectionPoolCreatedEvent -import io.micrometer.binder.mongodb.MongoConnectionPoolTagsProvider import io.micrometer.core.instrument.Tag +import io.micrometer.core.instrument.binder.mongodb.MongoConnectionPoolTagsProvider class CustomConnectionPoolTagsProvider : MongoConnectionPoolTagsProvider { diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/MyConnectionPoolTagsProviderConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/MyConnectionPoolTagsProviderConfiguration.kt index 260b889cbb44..0c56242fa3a9 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/MyConnectionPoolTagsProviderConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/MyConnectionPoolTagsProviderConfiguration.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.actuator.metrics.supported.mongodb.connectionpool -import io.micrometer.binder.mongodb.MongoConnectionPoolTagsProvider +import io.micrometer.core.instrument.binder.mongodb.MongoConnectionPoolTagsProvider import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.kt index 1a8be789a4b0..b9b8b0e301d9 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.kt @@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest.WebEnvironment -import org.springframework.boot.web.server.LocalServerPort +import org.springframework.boot.test.web.server.LocalServerPort import org.springframework.restdocs.restassured.RestAssuredRestDocumentation @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @@ -41,4 +41,4 @@ class MyUserDocumentationTests { .statusCode(Matchers.`is`(200)) } -} \ No newline at end of file +} diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.kt index 627bd8b3fb96..12b182578b3d 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.kt @@ -18,7 +18,7 @@ package org.springframework.boot.docs.howto.webserver.discoverport import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest.WebEnvironment -import org.springframework.boot.web.server.LocalServerPort +import org.springframework.boot.test.web.server.LocalServerPort @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class MyWebIntegrationTests { diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-actuator/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-actuator/build.gradle index 74a593dd2906..3e2a471593a3 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-actuator/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-actuator/build.gradle @@ -9,5 +9,4 @@ dependencies { api(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) api("io.micrometer:micrometer-observation") api("io.micrometer:micrometer-core") - api("io.micrometer:micrometer-binders") } diff --git a/spring-boot-project/spring-boot-test-autoconfigure/build.gradle b/spring-boot-project/spring-boot-test-autoconfigure/build.gradle index 615c1c88c45a..6a5e602f328f 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-test-autoconfigure/build.gradle @@ -68,7 +68,6 @@ dependencies { testImplementation("com.unboundid:unboundid-ldapsdk") testImplementation("io.lettuce:lettuce-core") testImplementation("io.micrometer:micrometer-registry-prometheus") - testImplementation("io.micrometer:micrometer-binders") testImplementation("io.projectreactor.netty:reactor-netty-http") testImplementation("io.projectreactor:reactor-core") testImplementation("io.projectreactor:reactor-test") diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java index c869a9472462..4a83fc38b630 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java @@ -26,8 +26,8 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.testsupport.BuildOutput; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.annotation.Bean; import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation; import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationIntegrationTests.java index 092daf284e99..5d763f790b31 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationIntegrationTests.java @@ -25,8 +25,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.testsupport.BuildOutput; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.util.FileSystemUtils; import static io.restassured.RestAssured.given; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java index 148c2f41e7f1..3e0e48bf448d 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java @@ -55,6 +55,7 @@ import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; +import org.springframework.web.context.ConfigurableWebApplicationContext; import org.springframework.web.context.support.GenericWebApplicationContext; /** @@ -103,14 +104,21 @@ public ApplicationContext loadContext(MergedContextConfiguration config) throws } else if (config instanceof ReactiveWebMergedContextConfiguration) { application.setWebApplicationType(WebApplicationType.REACTIVE); - if (!isEmbeddedWebEnvironment(config)) { - application.setApplicationContextFactory( - ApplicationContextFactory.of(GenericReactiveWebApplicationContext::new)); - } } else { application.setWebApplicationType(WebApplicationType.NONE); } + application.setApplicationContextFactory((type) -> { + if (type != WebApplicationType.NONE && !isEmbeddedWebEnvironment(config)) { + if (type == WebApplicationType.REACTIVE) { + return new GenericReactiveWebApplicationContext(); + } + else if (type == WebApplicationType.SERVLET) { + return new GenericWebApplicationContext(); + } + } + return ApplicationContextFactory.DEFAULT.create(type); + }); application.setInitializers(initializers); ConfigurableEnvironment environment = getEnvironment(); if (environment != null) { @@ -261,14 +269,38 @@ void configure(MergedContextConfiguration configuration, SpringApplication appli List> initializers) { WebMergedContextConfiguration webConfiguration = (WebMergedContextConfiguration) configuration; addMockServletContext(initializers, webConfiguration); - application.setApplicationContextFactory((webApplicationType) -> new GenericWebApplicationContext()); } private void addMockServletContext(List> initializers, WebMergedContextConfiguration webConfiguration) { SpringBootMockServletContext servletContext = new SpringBootMockServletContext( webConfiguration.getResourceBasePath()); - initializers.add(0, new ServletContextApplicationContextInitializer(servletContext, true)); + initializers.add(0, new DefensiveWebApplicationContextInitializer( + new ServletContextApplicationContextInitializer(servletContext, true))); + } + + /** + * Decorator for {@link ServletContextApplicationContextInitializer} that prevents + * a failure when the context type is not as was predicted when the initializer + * was registered. This can occur when spring.main.web-application-type is set to + * something other than servlet. + */ + private static final class DefensiveWebApplicationContextInitializer + implements ApplicationContextInitializer { + + private final ServletContextApplicationContextInitializer delegate; + + private DefensiveWebApplicationContextInitializer(ServletContextApplicationContextInitializer delegate) { + this.delegate = delegate; + } + + @Override + public void initialize(ConfigurableApplicationContext applicationContext) { + if (applicationContext instanceof ConfigurableWebApplicationContext) { + this.delegate.initialize((ConfigurableWebApplicationContext) applicationContext); + } + } + } } diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTest.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTest.java index d069745393f4..6fed9ffb26df 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTest.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-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. @@ -29,8 +29,8 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.WebApplicationType; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java index 31ae6e769a56..c89ae886da43 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -290,9 +290,13 @@ protected void processPropertySourceProperties(MergedContextConfiguration merged // precedence propertySourceProperties.addAll(0, Arrays.asList(properties)); } - if (getWebEnvironment(testClass) == WebEnvironment.RANDOM_PORT) { + WebEnvironment webEnvironment = getWebEnvironment(testClass); + if (webEnvironment == WebEnvironment.RANDOM_PORT) { propertySourceProperties.add("server.port=0"); } + else if (webEnvironment == WebEnvironment.NONE) { + propertySourceProperties.add("spring.main.web-application-type=none"); + } } /** diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/rsocket/server/LocalRSocketServerPort.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/rsocket/server/LocalRSocketServerPort.java new file mode 100644 index 000000000000..a80e6cf6143e --- /dev/null +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/rsocket/server/LocalRSocketServerPort.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-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.boot.test.rsocket.server; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.beans.factory.annotation.Value; + +/** + * Annotation at the field or method/constructor parameter level that injects the RSocket + * port that was allocated at runtime. Provides a convenient alternative for + * @Value("${local.rsocket.server.port}"). + * + * @author Verónica Vásquez + * @author Eddú Meléndez + * @since 2.7.0 + */ +@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Value("${local.rsocket.server.port}") +public @interface LocalRSocketServerPort { + +} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/rsocket/server/package-info.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/rsocket/server/package-info.java new file mode 100644 index 000000000000..579c40b36497 --- /dev/null +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/rsocket/server/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-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. + */ + +/** + * RSocket server test utilities and support classes. + */ +package org.springframework.boot.test.rsocket.server; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalManagementPort.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalManagementPort.java new file mode 100644 index 000000000000..a5a51f016c48 --- /dev/null +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalManagementPort.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012-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.boot.test.web.server; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.beans.factory.annotation.Value; + +/** + * Annotation at the field or method/constructor parameter level that injects the HTTP + * management port that was allocated at runtime. Provides a convenient alternative for + * @Value("${local.management.port}"). + * + * @author Stephane Nicoll + * @since 2.7.0 + */ +@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Value("${local.management.port}") +public @interface LocalManagementPort { + +} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalServerPort.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalServerPort.java new file mode 100644 index 000000000000..ff7929ca6873 --- /dev/null +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalServerPort.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-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.boot.test.web.server; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.beans.factory.annotation.Value; + +/** + * Annotation at the field or method/constructor parameter level that injects the HTTP + * server port that was allocated at runtime. Provides a convenient alternative for + * @Value("${local.server.port}"). + * + * @author Anand Shah + * @author Stephane Nicoll + * @since 2.7.0 + */ +@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Value("${local.server.port}") +public @interface LocalServerPort { + +} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/package-info.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/package-info.java new file mode 100644 index 000000000000..3fd756a102bc --- /dev/null +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-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. + */ + +/** + * Web server test utilities and support classes. + */ +package org.springframework.boot.test.web.server; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java index 2aa871007d6d..24fa63ae5e2f 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -24,10 +24,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestWebServerWebEnvironmentTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestWebServerWebEnvironmentTests.java index dbe55f5ce0b0..5f81f51cfa00 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestWebServerWebEnvironmentTests.java +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestWebServerWebEnvironmentTests.java @@ -22,8 +22,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootContextLoaderTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootContextLoaderTests.java index ad03d67f4a02..3b9f4a5050b1 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootContextLoaderTests.java +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootContextLoaderTests.java @@ -24,6 +24,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.boot.web.reactive.context.GenericReactiveWebApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.ConfigurableEnvironment; @@ -36,6 +37,7 @@ import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.support.TestPropertySourceUtils; import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.web.context.WebApplicationContext; import static org.assertj.core.api.Assertions.assertThat; @@ -146,6 +148,20 @@ void propertySourceOrdering() throws Exception { assertThat(last).startsWith("Config resource"); } + @Test + void whenEnvironmentChangesWebApplicationTypeToNoneThenContextTypeChangesAccordingly() { + TestContext context = new ExposedTestContextManager(ChangingWebApplicationTypeToNone.class) + .getExposedTestContext(); + assertThat(context.getApplicationContext()).isNotInstanceOf(WebApplicationContext.class); + } + + @Test + void whenEnvironmentChangesWebApplicationTypeToReactiveThenContextTypeChangesAccordingly() { + TestContext context = new ExposedTestContextManager(ChangingWebApplicationTypeToReactive.class) + .getExposedTestContext(); + assertThat(context.getApplicationContext()).isInstanceOf(GenericReactiveWebApplicationContext.class); + } + private String[] getActiveProfiles(Class testClass) { TestContext testContext = new ExposedTestContextManager(testClass).getExposedTestContext(); ApplicationContext applicationContext = testContext.getApplicationContext(); @@ -228,6 +244,16 @@ static class Config { } + @SpringBootTest(classes = Config.class, args = "--spring.main.web-application-type=none") + static class ChangingWebApplicationTypeToNone { + + } + + @SpringBootTest(classes = Config.class, args = "--spring.main.web-application-type=reactive") + static class ChangingWebApplicationTypeToReactive { + + } + /** * {@link TestContextManager} which exposes the {@link TestContext}. */ diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/rsocket/server/LocalRSocketServerPortTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/rsocket/server/LocalRSocketServerPortTests.java new file mode 100644 index 000000000000..59b12f58d20d --- /dev/null +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/rsocket/server/LocalRSocketServerPortTests.java @@ -0,0 +1,55 @@ +/* + * Copyright 2012-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.boot.test.rsocket.server; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link LocalRSocketServerPort @LocalRSocketServerPort}. + * + * @author Verónica Vásquez + * @author Eddú Meléndez + */ +@ExtendWith(SpringExtension.class) +@TestPropertySource(properties = "local.rsocket.server.port=8181") +class LocalRSocketServerPortTests { + + @Value("${local.rsocket.server.port}") + private String fromValue; + + @LocalRSocketServerPort + private String fromAnnotation; + + @Test + void testLocalRSocketServerPortAnnotation() { + assertThat(this.fromAnnotation).isNotNull().isEqualTo(this.fromValue); + } + + @Configuration(proxyBeanMethods = false) + static class Config { + + } + +} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalManagementPortTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalManagementPortTests.java new file mode 100644 index 000000000000..8be0c26f78ce --- /dev/null +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalManagementPortTests.java @@ -0,0 +1,54 @@ +/* + * Copyright 2012-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.boot.test.web.server; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link LocalManagementPort @LocalManagementPort}. + * + * @author Andy Wilkinson + */ +@ExtendWith(SpringExtension.class) +@TestPropertySource(properties = "local.management.port=8181") +class LocalManagementPortTests { + + @Value("${local.management.port}") + private String fromValue; + + @LocalManagementPort + private String fromAnnotation; + + @Test + void testLocalManagementPortAnnotation() { + assertThat(this.fromAnnotation).isNotNull().isEqualTo(this.fromValue); + } + + @Configuration(proxyBeanMethods = false) + static class Config { + + } + +} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalServerPortTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalServerPortTests.java new file mode 100644 index 000000000000..3855f5115f7c --- /dev/null +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalServerPortTests.java @@ -0,0 +1,55 @@ +/* + * Copyright 2012-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.boot.test.web.server; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link LocalServerPort @LocalServerPort}. + * + * @author Anand Shah + * @author Phillip Webb + */ +@ExtendWith(SpringExtension.class) +@TestPropertySource(properties = "local.server.port=8181") +class LocalServerPortTests { + + @Value("${local.server.port}") + private String fromValue; + + @LocalServerPort + private String fromAnnotation; + + @Test + void testLocalServerPortAnnotation() { + assertThat(this.fromAnnotation).isNotNull().isEqualTo(this.fromValue); + } + + @Configuration(proxyBeanMethods = false) + static class Config { + + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/ApiVersions.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/ApiVersions.java index fdbef611d6f6..9b02d9796b98 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/ApiVersions.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/ApiVersions.java @@ -17,8 +17,7 @@ package org.springframework.boot.buildpack.platform.build; import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; +import java.util.stream.IntStream; import org.springframework.util.StringUtils; @@ -32,8 +31,7 @@ final class ApiVersions { /** * The platform API versions supported by this release. */ - static final ApiVersions SUPPORTED_PLATFORMS = new ApiVersions(ApiVersion.of(0, 3), ApiVersion.of(0, 4), - ApiVersion.of(0, 5), ApiVersion.of(0, 6), ApiVersion.of(0, 7), ApiVersion.of(0, 8)); + static final ApiVersions SUPPORTED_PLATFORMS = ApiVersions.of(0, IntStream.rangeClosed(3, 9)); private final ApiVersion[] apiVersions; @@ -92,8 +90,12 @@ public String toString() { * @throws IllegalArgumentException if any values could not be parsed */ static ApiVersions parse(String... values) { - List versions = Arrays.stream(values).map(ApiVersion::parse).collect(Collectors.toList()); - return new ApiVersions(versions.toArray(new ApiVersion[] {})); + return new ApiVersions(Arrays.stream(values).map(ApiVersion::parse).toArray(ApiVersion[]::new)); + } + + static ApiVersions of(int major, IntStream minorsInclusive) { + return new ApiVersions( + minorsInclusive.mapToObj((minor) -> ApiVersion.of(major, minor)).toArray(ApiVersion[]::new)); } } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/ApiVersionsTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/ApiVersionsTests.java index 421f2a191062..cdaa17d9dd39 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/ApiVersionsTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/ApiVersionsTests.java @@ -16,6 +16,8 @@ package org.springframework.boot.buildpack.platform.build; +import java.util.stream.IntStream; + import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -65,6 +67,12 @@ void findLatestWhenNoneSupportedThrowsException() { "Detected platform API versions '1.3,1.4' are not included in supported versions '1.1,1.2'"); } + @Test + void createFromRange() { + ApiVersions versions = ApiVersions.of(1, IntStream.rangeClosed(2, 7)); + assertThat(versions.toString()).isEqualTo("1.2,1.3,1.4,1.5,1.6,1.7"); + } + @Test void toStringReturnsString() { assertThat(ApiVersions.parse("1.1", "2.2", "3.3").toString()).isEqualTo("1.1,2.2,3.3"); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/LifecycleTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/LifecycleTests.java index 6aa6f04c81ba..a641427c28ae 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/LifecycleTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/LifecycleTests.java @@ -161,8 +161,8 @@ void executeWhenPlatformApiNotSupportedThrowsException() throws Exception { given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId()); given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null)); assertThatIllegalStateException() - .isThrownBy(() -> createLifecycle("builder-metadata-unsupported-api.json").execute()).withMessage( - "Detected platform API versions '0.2' are not included in supported versions '0.3,0.4,0.5,0.6,0.7,0.8'"); + .isThrownBy(() -> createLifecycle("builder-metadata-unsupported-api.json").execute()) + .withMessageContaining("Detected platform API versions '0.2' are not included in supported versions"); } @Test @@ -171,8 +171,9 @@ void executeWhenMultiplePlatformApisNotSupportedThrowsException() throws Excepti given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId()); given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null)); assertThatIllegalStateException() - .isThrownBy(() -> createLifecycle("builder-metadata-unsupported-apis.json").execute()).withMessage( - "Detected platform API versions '0.1,0.2' are not included in supported versions '0.3,0.4,0.5,0.6,0.7,0.8'"); + .isThrownBy(() -> createLifecycle("builder-metadata-unsupported-apis.json").execute()) + .withMessageContaining( + "Detected platform API versions '0.1,0.2' are not included in supported versions"); } @Test diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataGenerationEnvironment.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataGenerationEnvironment.java index fc0580285ddf..12e74e475963 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataGenerationEnvironment.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataGenerationEnvironment.java @@ -221,10 +221,6 @@ List getElementsAnnotatedOrMetaAnnotatedWith(Element element, TypeEleme return Collections.unmodifiableList(stack); } - private boolean hasAnnotationRecursive(Element element, String type) { - return !getElementsAnnotatedOrMetaAnnotatedWith(element, this.elements.getTypeElement(type)).isEmpty(); - } - private boolean collectElementsAnnotatedOrMetaAnnotatedWith(TypeElement annotationType, LinkedList stack) { Element element = stack.peekLast(); for (AnnotationMirror annotation : this.elements.getAllAnnotationMirrors(element)) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/running.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/running.adoc index 9c230e6f7121..b178f1277625 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/running.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/running.adoc @@ -123,7 +123,7 @@ The preceding example sets the value of the `example` project property to `custo [[running-your-application.reloading-resources]] == Reloading Resources If devtools has been added to your project it will automatically monitor your application's classpath for changes. -Note that modified files need to be recompiled for the classpath to update inorder to trigger reloading with devtools. +Note that modified files need to be recompiled for the classpath to update in order to trigger reloading with devtools. For more details on using devtools, refer to {spring-boot-reference}#using.devtools.restart[this section of the reference documentation]. Alternatively, you can configure `bootRun` such that your application's static resources are loaded from their source location: diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java index 315d587220f3..993937d7b0e7 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -110,7 +110,7 @@ public void properties(Action action) { private Map coerceToStringValues(Map input) { Map output = new HashMap<>(); - input.forEach((key, value) -> output.put(key, value.toString())); + input.forEach((key, value) -> output.put(key, (value != null) ? value.toString() : null)); return output; } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java index 441ebd4d2459..e1c86f4ab761 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -33,6 +33,7 @@ import org.springframework.boot.testsupport.classpath.ClassPathExclusions; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * Tests for {@link BuildInfo}. @@ -186,6 +187,14 @@ void additionalPropertiesAreReflectedInProperties() { assertThat(buildInfoProperties(task)).containsEntry("build.b", "bravo"); } + @Test + void nullAdditionalPropertyProducesInformativeFailure() { + BuildInfo task = createTask(createProject("test")); + task.getProperties().getAdditional().put("a", null); + assertThatThrownBy(() -> buildInfoProperties(task)) + .hasMessage("Additional property 'a' is illegal as its value is null"); + } + private Project createProject(String projectName) { File projectDir = new File(this.temp, projectName); Project project = GradleProjectBuilder.builder().withProjectDir(projectDir).withName(projectName).build(); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-test-support/src/main/java/org/springframework/boot/testsupport/gradle/testkit/GradleBuild.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-test-support/src/main/java/org/springframework/boot/testsupport/gradle/testkit/GradleBuild.java index b9ecb49186fb..7268df47aa1c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-test-support/src/main/java/org/springframework/boot/testsupport/gradle/testkit/GradleBuild.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-test-support/src/main/java/org/springframework/boot/testsupport/gradle/testkit/GradleBuild.java @@ -184,7 +184,7 @@ public BuildResult build(String... arguments) { buildOutput = buildOutput.replaceAll(message, ""); } } - assertThat(buildOutput).doesNotContain("Deprecated").doesNotContain("deprecated"); + assertThat(buildOutput).doesNotContainIgnoringCase("deprecated"); } return result; } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ExitCodeGenerators.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ExitCodeGenerators.java index f26f16ea166d..489f23ec8715 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ExitCodeGenerators.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ExitCodeGenerators.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -21,14 +21,19 @@ import java.util.Iterator; import java.util.List; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.AnnotationAwareOrderComparator; +import org.springframework.core.annotation.Order; import org.springframework.util.Assert; /** - * Maintains a collection of {@link ExitCodeGenerator} instances and allows the final exit - * code to be calculated. + * Maintains an ordered collection of {@link ExitCodeGenerator} instances and allows the + * final exit code to be calculated. Generators are ordered by {@link Order @Order} and + * {@link Ordered}. * * @author Dave Syer * @author Phillip Webb + * @author GenKui Du * @see #getExitCode() * @see ExitCodeGenerator */ @@ -71,6 +76,7 @@ void addAll(Iterable generators) { void add(ExitCodeGenerator generator) { Assert.notNull(generator, "Generator must not be null"); this.generators.add(generator); + AnnotationAwareOrderComparator.sort(this.generators); } @Override @@ -79,7 +85,8 @@ public Iterator iterator() { } /** - * Get the final exit code that should be returned based on all contained generators. + * Get the final exit code that should be returned. The final exit code is the first + * non-zero exit code that is {@link ExitCodeGenerator#getExitCode generated}. * @return the final exit code. */ int getExitCode() { @@ -87,12 +94,13 @@ int getExitCode() { for (ExitCodeGenerator generator : this.generators) { try { int value = generator.getExitCode(); - if (value > 0 && value > exitCode || value < 0 && value < exitCode) { + if (value != 0) { exitCode = value; + break; } } catch (Exception ex) { - exitCode = (exitCode != 0) ? exitCode : 1; + exitCode = 1; ex.printStackTrace(); } } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java index 7f1910c61124..e3075cad8b7b 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java @@ -61,7 +61,9 @@ import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.GenericTypeResolver; +import org.springframework.core.Ordered; import org.springframework.core.annotation.AnnotationAwareOrderComparator; +import org.springframework.core.annotation.Order; import org.springframework.core.env.CommandLinePropertySource; import org.springframework.core.env.CompositePropertySource; import org.springframework.core.env.ConfigurableEnvironment; @@ -1320,9 +1322,10 @@ public static void main(String[] args) throws Exception { * Static helper that can be used to exit a {@link SpringApplication} and obtain a * code indicating success (0) or otherwise. Does not throw exceptions but should * print stack traces of any encountered. Applies the specified - * {@link ExitCodeGenerator} in addition to any Spring beans that implement - * {@link ExitCodeGenerator}. In the case of multiple exit codes the highest value - * will be used (or if all values are negative, the lowest value will be used) + * {@link ExitCodeGenerator ExitCodeGenerators} in addition to any Spring beans that + * implement {@link ExitCodeGenerator}. When multiple generators are available, the + * first non-zero exit code is used. Generators ordered based on their {@link Ordered} + * implementation and {@link Order @Order} annotation. * @param context the context to close if possible * @param exitCodeGenerators exit code generators * @return the outcome (0 if successful) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/annotation/Configurations.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/annotation/Configurations.java index 59056d2e8e1a..522c1469bc83 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/annotation/Configurations.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/annotation/Configurations.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -33,6 +33,7 @@ import org.springframework.context.annotation.ImportSelector; import org.springframework.core.OrderComparator; import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -47,8 +48,8 @@ * This class is primarily intended for use with tests that need to specify configuration * classes but can't use {@link SpringRunner}. *

- * Implementations of this class should be annotated with {@code @Order} or implement - * {@link Ordered}. + * Implementations of this class should be annotated with {@link Order @Order} or + * implement {@link Ordered}. * * @author Phillip Webb * @since 2.0.0 diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBean.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBean.java index be59be46351b..ecf7e2732cc3 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBean.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBean.java @@ -148,8 +148,12 @@ public static Map getAll(ApplicationContext return getAll((ConfigurableApplicationContext) applicationContext); } Map propertiesBeans = new LinkedHashMap<>(); - applicationContext.getBeansWithAnnotation(ConfigurationProperties.class) - .forEach((beanName, bean) -> propertiesBeans.put(beanName, get(applicationContext, bean, beanName))); + applicationContext.getBeansWithAnnotation(ConfigurationProperties.class).forEach((beanName, bean) -> { + ConfigurationPropertiesBean propertiesBean = get(applicationContext, bean, beanName); + if (propertiesBean != null) { + propertiesBeans.put(beanName, propertiesBean); + } + }); return propertiesBeans; } @@ -163,7 +167,9 @@ private static Map getAll(ConfigurableAppli try { Object bean = beanFactory.getBean(beanName); ConfigurationPropertiesBean propertiesBean = get(applicationContext, bean, beanName); - propertiesBeans.put(beanName, propertiesBean); + if (propertiesBean != null) { + propertiesBeans.put(beanName, propertiesBean); + } } catch (Exception ex) { } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/FailureAnalyzers.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/FailureAnalyzers.java index df040bfb8681..d493c47894e3 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/FailureAnalyzers.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/FailureAnalyzers.java @@ -90,9 +90,9 @@ private List handleAwareAnalyzers(List analyze String awareAnalyzerNames = StringUtils.collectionToCommaDelimitedString(awareAnalyzers.stream() .map((analyzer) -> analyzer.getClass().getName()).collect(Collectors.toList())); logger.warn(LogMessage.format( - "FailureAnalyzers [%s] implement BeanFactoryAware or EnvironmentAware." + "FailureAnalyzers [%s] implement BeanFactoryAware or EnvironmentAware. " + "Support for these interfaces on FailureAnalyzers is deprecated, " - + "and will be removed in a future release." + + "and will be removed in a future release. " + "Instead provide a constructor that accepts BeanFactory or Environment parameters.", awareAnalyzerNames)); if (context == null) { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/BeanCurrentlyInCreationFailureAnalyzer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/BeanCurrentlyInCreationFailureAnalyzer.java index aa9786023066..44de27d6cbd5 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/BeanCurrentlyInCreationFailureAnalyzer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/BeanCurrentlyInCreationFailureAnalyzer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -19,11 +19,9 @@ import java.util.ArrayList; import java.util.List; -import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanCurrentlyInCreationException; import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.InjectionPoint; import org.springframework.beans.factory.UnsatisfiedDependencyException; import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory; @@ -36,17 +34,19 @@ * {@link BeanCurrentlyInCreationException}. * * @author Andy Wilkinson + * @author Scott Frederick */ -class BeanCurrentlyInCreationFailureAnalyzer extends AbstractFailureAnalyzer - implements BeanFactoryAware { +class BeanCurrentlyInCreationFailureAnalyzer extends AbstractFailureAnalyzer { - private AbstractAutowireCapableBeanFactory beanFactory; + private final AbstractAutowireCapableBeanFactory beanFactory; - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - if (beanFactory instanceof AbstractAutowireCapableBeanFactory) { + BeanCurrentlyInCreationFailureAnalyzer(BeanFactory beanFactory) { + if (beanFactory != null && beanFactory instanceof AbstractAutowireCapableBeanFactory) { this.beanFactory = (AbstractAutowireCapableBeanFactory) beanFactory; } + else { + this.beanFactory = null; + } } @Override diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/InvalidConfigurationPropertyValueFailureAnalyzer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/InvalidConfigurationPropertyValueFailureAnalyzer.java index e9ab9ab6cdfb..7f1cff00907b 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/InvalidConfigurationPropertyValueFailureAnalyzer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/InvalidConfigurationPropertyValueFailureAnalyzer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -27,7 +27,6 @@ import org.springframework.boot.diagnostics.FailureAnalyzer; import org.springframework.boot.origin.Origin; import org.springframework.boot.origin.OriginLookup; -import org.springframework.context.EnvironmentAware; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; import org.springframework.core.env.PropertySource; @@ -38,14 +37,14 @@ * {@link InvalidConfigurationPropertyValueException}. * * @author Stephane Nicoll + * @author Scott Frederick */ class InvalidConfigurationPropertyValueFailureAnalyzer - extends AbstractFailureAnalyzer implements EnvironmentAware { + extends AbstractFailureAnalyzer { - private ConfigurableEnvironment environment; + private final ConfigurableEnvironment environment; - @Override - public void setEnvironment(Environment environment) { + InvalidConfigurationPropertyValueFailureAnalyzer(Environment environment) { this.environment = (ConfigurableEnvironment) environment; } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/MutuallyExclusiveConfigurationPropertiesFailureAnalyzer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/MutuallyExclusiveConfigurationPropertiesFailureAnalyzer.java index 429aa21f5fc3..56bac16c92c1 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/MutuallyExclusiveConfigurationPropertiesFailureAnalyzer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/MutuallyExclusiveConfigurationPropertiesFailureAnalyzer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -32,24 +32,23 @@ import org.springframework.boot.diagnostics.FailureAnalyzer; import org.springframework.boot.origin.Origin; import org.springframework.boot.origin.OriginLookup; -import org.springframework.context.EnvironmentAware; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; import org.springframework.core.env.PropertySource; /** - * A {@link FailureAnalyzer} that performs analysis of failures caused by an + * A {@link FailureAnalyzer} that performs analysis of failures caused by a * {@link MutuallyExclusiveConfigurationPropertiesException}. * * @author Andy Wilkinson + * @author Scott Frederick */ class MutuallyExclusiveConfigurationPropertiesFailureAnalyzer - extends AbstractFailureAnalyzer implements EnvironmentAware { + extends AbstractFailureAnalyzer { - private ConfigurableEnvironment environment; + private final ConfigurableEnvironment environment; - @Override - public void setEnvironment(Environment environment) { + MutuallyExclusiveConfigurationPropertiesFailureAnalyzer(Environment environment) { this.environment = (ConfigurableEnvironment) environment; } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzer.java index aa2e540954ba..555df79bce1f 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -16,9 +16,7 @@ package org.springframework.boot.diagnostics.analyzer; -import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.NoUniqueBeanDefinitionException; import org.springframework.beans.factory.config.BeanDefinition; @@ -32,14 +30,13 @@ * by a {@link NoUniqueBeanDefinitionException}. * * @author Andy Wilkinson + * @author Scott Frederick */ -class NoUniqueBeanDefinitionFailureAnalyzer extends AbstractInjectionFailureAnalyzer - implements BeanFactoryAware { +class NoUniqueBeanDefinitionFailureAnalyzer extends AbstractInjectionFailureAnalyzer { - private ConfigurableBeanFactory beanFactory; + private final ConfigurableBeanFactory beanFactory; - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + NoUniqueBeanDefinitionFailureAnalyzer(BeanFactory beanFactory) { Assert.isInstanceOf(ConfigurableBeanFactory.class, beanFactory); this.beanFactory = (ConfigurableBeanFactory) beanFactory; } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DatabaseDriver.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DatabaseDriver.java index 8b682f6d482c..03ba0c1deff6 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DatabaseDriver.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DatabaseDriver.java @@ -76,11 +76,6 @@ public enum DatabaseDriver { */ MARIADB("MariaDB", "org.mariadb.jdbc.Driver", "org.mariadb.jdbc.MariaDbDataSource", "SELECT 1"), - /** - * Google App Engine. - */ - GAE(null, "com.google.appengine.api.rdbms.AppEngineDriver"), - /** * Oracle. */ diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/LocalRSocketServerPort.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/LocalRSocketServerPort.java index 7da1f6a32c93..b64f4ca3d5ca 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/LocalRSocketServerPort.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/LocalRSocketServerPort.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -32,11 +32,14 @@ * @author Verónica Vásquez * @author Eddú Meléndez * @since 2.2.0 + * @deprecated since 2.7.0 for removal in 2.9.0 in favor of + * {@code org.springframework.boot.test.rsocket.LocalRSocketServerPort} */ @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) @Retention(RetentionPolicy.RUNTIME) @Documented @Value("${local.rsocket.server.port}") +@Deprecated public @interface LocalRSocketServerPort { } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java index 1ea7e2b80124..89f44959ede4 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -39,6 +39,7 @@ import org.springframework.boot.rsocket.server.RSocketServer; import org.springframework.boot.rsocket.server.RSocketServerCustomizer; import org.springframework.boot.rsocket.server.RSocketServerFactory; +import org.springframework.boot.web.server.CertificateFileSslStoreProvider; import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.SslStoreProvider; import org.springframework.http.client.reactive.ReactorResourceFactory; @@ -51,6 +52,7 @@ * * @author Brian Clozel * @author Chris Bono + * @author Scott Frederick * @since 2.2.0 */ public class NettyRSocketServerFactory implements RSocketServerFactory, ConfigurableRSocketServerFactory { @@ -179,7 +181,7 @@ private ServerTransport createWebSocketTransport() { @SuppressWarnings("deprecation") private HttpServer customizeSslConfiguration(HttpServer httpServer) { org.springframework.boot.web.embedded.netty.SslServerCustomizer sslServerCustomizer = new org.springframework.boot.web.embedded.netty.SslServerCustomizer( - this.ssl, null, this.sslStoreProvider); + this.ssl, null, getOrCreateSslStoreProvider()); return sslServerCustomizer.apply(httpServer); } @@ -189,12 +191,20 @@ private ServerTransport createTcpTransport() { tcpServer = tcpServer.runOn(this.resourceFactory.getLoopResources()); } if (this.ssl != null && this.ssl.isEnabled()) { - TcpSslServerCustomizer sslServerCustomizer = new TcpSslServerCustomizer(this.ssl, this.sslStoreProvider); + TcpSslServerCustomizer sslServerCustomizer = new TcpSslServerCustomizer(this.ssl, + getOrCreateSslStoreProvider()); tcpServer = sslServerCustomizer.apply(tcpServer); } return TcpServerTransport.create(tcpServer.bindAddress(this::getListenAddress)); } + private SslStoreProvider getOrCreateSslStoreProvider() { + if (this.sslStoreProvider != null) { + return this.sslStoreProvider; + } + return CertificateFileSslStoreProvider.from(this.ssl); + } + private InetSocketAddress getListenAddress() { if (this.address != null) { return new InetSocketAddress(this.address.getHostAddress(), this.port); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanException.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanException.java new file mode 100644 index 000000000000..5585fc49d416 --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanException.java @@ -0,0 +1,59 @@ +/* + * Copyright 2012-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.boot.web.context; + +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.web.server.WebServerFactory; + +/** + * Exception thrown when there is no {@link WebServerFactory} bean of the required type + * defined in a {@link WebServerApplicationContext}. + * + * @author Guirong Hu + * @author Andy Wilkinson + * @since 2.7.0 + */ +public class MissingWebServerFactoryBeanException extends NoSuchBeanDefinitionException { + + private final WebApplicationType webApplicationType; + + /** + * Create a new {@code MissingWebServerFactoryBeanException}. + * @param webServerApplicationContextClass the class of the + * WebServerApplicationContext that required the WebServerFactory + * @param webServerFactoryClass the class of the WebServerFactory that was missing + * @param webApplicationType the type of the web application + */ + public MissingWebServerFactoryBeanException( + Class webServerApplicationContextClass, + Class webServerFactoryClass, WebApplicationType webApplicationType) { + super(webServerFactoryClass, String.format("Unable to start %s due to missing %s bean", + webServerApplicationContextClass.getSimpleName(), webServerFactoryClass.getSimpleName())); + this.webApplicationType = webApplicationType; + } + + /** + * Returns the type of web application for which a {@link WebServerFactory} bean was + * missing. + * @return the type of web application + */ + public WebApplicationType getWebApplicationType() { + return this.webApplicationType; + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzer.java new file mode 100644 index 000000000000..d27cdd786130 --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzer.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-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.boot.web.context; + +import java.util.Locale; + +import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; +import org.springframework.boot.diagnostics.FailureAnalysis; +import org.springframework.boot.diagnostics.FailureAnalyzer; +import org.springframework.core.annotation.Order; + +/** + * A {@link FailureAnalyzer} that performs analysis of failures caused by a + * {@link MissingWebServerFactoryBeanException}. + * + * @author Guirong Hu + * @author Andy Wilkinson + */ +@Order(0) +class MissingWebServerFactoryBeanFailureAnalyzer extends AbstractFailureAnalyzer { + + @Override + protected FailureAnalysis analyze(Throwable rootFailure, MissingWebServerFactoryBeanException cause) { + return new FailureAnalysis( + "Web application could not be started as there was no " + cause.getBeanType().getName() + + " bean defined in the context.", + "Check your application's dependencies for a supported " + + cause.getWebApplicationType().name().toLowerCase(Locale.ENGLISH) + " web server.\n" + + "Check the configured web application type.", + cause); + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactory.java index 531667de61a1..223058f7202a 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -236,7 +236,7 @@ private Handler applyWrapper(Handler handler, HandlerWrapper wrapper) { } private void customizeSsl(Server server, InetSocketAddress address) { - new SslServerCustomizer(address, getSsl(), getSslStoreProvider(), getHttp2()).customize(server); + new SslServerCustomizer(address, getSsl(), getOrCreateSslStoreProvider(), getHttp2()).customize(server); } } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java index cf28b85c2f08..40f3ba7cf0cd 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java @@ -220,7 +220,7 @@ private Handler applyWrapper(Handler handler, HandlerWrapper wrapper) { } private void customizeSsl(Server server, InetSocketAddress address) { - new SslServerCustomizer(address, getSsl(), getSslStoreProvider(), getHttp2()).customize(server); + new SslServerCustomizer(address, getSsl(), getOrCreateSslStoreProvider(), getHttp2()).customize(server); } /** diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyReactiveWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyReactiveWebServerFactory.java index 78170a4ddf40..ae14a41c331c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyReactiveWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyReactiveWebServerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -179,7 +179,8 @@ private HttpServer createHttpServer() { @SuppressWarnings("deprecation") private HttpServer customizeSslConfiguration(HttpServer httpServer) { - SslServerCustomizer sslServerCustomizer = new SslServerCustomizer(getSsl(), getHttp2(), getSslStoreProvider()); + SslServerCustomizer sslServerCustomizer = new SslServerCustomizer(getSsl(), getHttp2(), + getOrCreateSslStoreProvider()); return sslServerCustomizer.apply(httpServer); } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactory.java index ca4a48a83c8e..6a76e0be7bc2 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactory.java @@ -221,7 +221,7 @@ private void customizeProtocol(AbstractProtocol protocol) { } private void customizeSsl(Connector connector) { - new SslConnectorCustomizer(getSsl(), getSslStoreProvider()).customize(connector); + new SslConnectorCustomizer(getSsl(), getOrCreateSslStoreProvider()).customize(connector); } @Override diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java index ff31364eb222..2f3eda5b2b8d 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java @@ -360,7 +360,7 @@ private void invokeProtocolHandlerCustomizers(ProtocolHandler protocolHandler) { } private void customizeSsl(Connector connector) { - new SslConnectorCustomizer(getSsl(), getSslStoreProvider()).customize(connector); + new SslConnectorCustomizer(getSsl(), getOrCreateSslStoreProvider()).customize(connector); } /** diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowWebServerFactoryDelegate.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowWebServerFactoryDelegate.java index 0b17e7a908c3..dc7482d4860e 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowWebServerFactoryDelegate.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowWebServerFactoryDelegate.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -163,7 +163,8 @@ Builder createBuilder(AbstractConfigurableWebServerFactory factory) { builder.setServerOption(UndertowOptions.ENABLE_HTTP2, http2.isEnabled()); } if (ssl != null && ssl.isEnabled()) { - new SslBuilderCustomizer(factory.getPort(), address, ssl, factory.getSslStoreProvider()).customize(builder); + new SslBuilderCustomizer(factory.getPort(), address, ssl, factory.getOrCreateSslStoreProvider()) + .customize(builder); } else { builder.addHttpListener(port, (address != null) ? address.getHostAddress() : "0.0.0.0"); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContext.java index 5a088e802fc7..f21b87e392db 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -18,9 +18,11 @@ import org.springframework.beans.BeansException; import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.boot.WebApplicationType; import org.springframework.boot.availability.AvailabilityChangeEvent; import org.springframework.boot.availability.ReadinessState; import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext; +import org.springframework.boot.web.context.MissingWebServerFactoryBeanException; import org.springframework.boot.web.context.WebServerGracefulShutdownLifecycle; import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; import org.springframework.boot.web.server.WebServer; @@ -105,8 +107,8 @@ protected String getWebServerFactoryBeanName() { // Use bean names so that we don't consider the hierarchy String[] beanNames = getBeanFactory().getBeanNamesForType(ReactiveWebServerFactory.class); if (beanNames.length == 0) { - throw new ApplicationContextException( - "Unable to start ReactiveWebApplicationContext due to missing ReactiveWebServerFactory bean."); + throw new MissingWebServerFactoryBeanException(getClass(), ReactiveWebServerFactory.class, + WebApplicationType.REACTIVE); } if (beanNames.length > 1) { throw new ApplicationContextException("Unable to start ReactiveWebApplicationContext due to multiple " diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java index 9e825504d0c1..f821882ddd54 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -100,7 +100,10 @@ private Map getErrorAttributes(ServerRequest request, boolean in private HttpStatus determineHttpStatus(Throwable error, MergedAnnotation responseStatusAnnotation) { if (error instanceof ResponseStatusException) { - return ((ResponseStatusException) error).getStatus(); + HttpStatus httpStatus = HttpStatus.resolve(((ResponseStatusException) error).getStatusCode().value()); + if (httpStatus != null) { + return httpStatus; + } } return responseStatusAnnotation.getValue("code", HttpStatus.class).orElse(HttpStatus.INTERNAL_SERVER_ERROR); } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/ReactiveWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/ReactiveWebServerFactory.java index 94f1b701aa82..101137d06498 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/ReactiveWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/ReactiveWebServerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -17,6 +17,7 @@ package org.springframework.boot.web.reactive.server; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.WebServerFactory; import org.springframework.http.server.reactive.HttpHandler; /** @@ -27,7 +28,7 @@ * @see WebServer */ @FunctionalInterface -public interface ReactiveWebServerFactory { +public interface ReactiveWebServerFactory extends WebServerFactory { /** * Gets a new fully configured but paused {@link WebServer} instance. Clients should diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/AbstractConfigurableWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/AbstractConfigurableWebServerFactory.java index fb29b31e0910..1cde582ced0f 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/AbstractConfigurableWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/AbstractConfigurableWebServerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-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. @@ -36,6 +36,7 @@ * @author Ivan Sopov * @author Eddú Meléndez * @author Brian Clozel + * @author Scott Frederick * @since 2.0.0 */ public abstract class AbstractConfigurableWebServerFactory implements ConfigurableWebServerFactory { @@ -179,6 +180,18 @@ public Shutdown getShutdown() { return this.shutdown; } + /** + * Return the provided {@link SslStoreProvider} or create one using {@link Ssl} + * properties. + * @return the {@code SslStoreProvider} + */ + public final SslStoreProvider getOrCreateSslStoreProvider() { + if (this.sslStoreProvider != null) { + return this.sslStoreProvider; + } + return CertificateFileSslStoreProvider.from(this.ssl); + } + /** * Return the absolute temp dir for given web server. * @param prefix server name diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/CertificateFileSslStoreProvider.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/CertificateFileSslStoreProvider.java new file mode 100644 index 000000000000..56480fb8f383 --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/CertificateFileSslStoreProvider.java @@ -0,0 +1,118 @@ +/* + * Copyright 2012-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.boot.web.server; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; + +/** + * An {@link SslStoreProvider} that creates key and trust stores from certificate and + * private key PEM files. + * + * @author Scott Frederick + * @since 2.7.0 + */ +public final class CertificateFileSslStoreProvider implements SslStoreProvider { + + private static final char[] NO_PASSWORD = {}; + + private static final String DEFAULT_KEY_ALIAS = "spring-boot-web"; + + private final Ssl ssl; + + private CertificateFileSslStoreProvider(Ssl ssl) { + this.ssl = ssl; + } + + @Override + public KeyStore getKeyStore() throws Exception { + return createKeyStore(this.ssl.getCertificate(), this.ssl.getCertificatePrivateKey(), + this.ssl.getKeyStorePassword(), this.ssl.getKeyStoreType(), this.ssl.getKeyAlias()); + } + + @Override + public KeyStore getTrustStore() throws Exception { + if (this.ssl.getTrustCertificate() == null) { + return null; + } + return createKeyStore(this.ssl.getTrustCertificate(), this.ssl.getTrustCertificatePrivateKey(), + this.ssl.getTrustStorePassword(), this.ssl.getTrustStoreType(), this.ssl.getKeyAlias()); + } + + /** + * Create a new {@link KeyStore} populated with the certificate stored at the + * specified file path and an optional private key. + * @param certPath the path to the certificate authority file + * @param keyPath the path to the private file + * @param password the key store password + * @param storeType the {@code KeyStore} type to create + * @param keyAlias the alias to use when adding keys to the {@code KeyStore} + * @return the {@code KeyStore} + */ + private KeyStore createKeyStore(String certPath, String keyPath, String password, String storeType, + String keyAlias) { + try { + KeyStore keyStore = KeyStore.getInstance((storeType != null) ? storeType : KeyStore.getDefaultType()); + keyStore.load(null); + X509Certificate[] certificates = CertificateParser.parse(certPath); + PrivateKey privateKey = (keyPath != null) ? PrivateKeyParser.parse(keyPath) : null; + try { + addCertificates(keyStore, certificates, privateKey, password, keyAlias); + } + catch (KeyStoreException ex) { + throw new IllegalStateException("Error adding certificates to KeyStore: " + ex.getMessage(), ex); + } + return keyStore; + } + catch (GeneralSecurityException | IOException ex) { + throw new IllegalStateException("Error creating KeyStore: " + ex.getMessage(), ex); + } + } + + private void addCertificates(KeyStore keyStore, X509Certificate[] certificates, PrivateKey privateKey, + String password, String keyAlias) throws KeyStoreException { + String alias = (keyAlias != null) ? keyAlias : DEFAULT_KEY_ALIAS; + if (privateKey != null) { + keyStore.setKeyEntry(alias, privateKey, ((password != null) ? password.toCharArray() : NO_PASSWORD), + certificates); + } + else { + for (int index = 0; index < certificates.length; index++) { + keyStore.setCertificateEntry(alias + "-" + index, certificates[index]); + } + } + } + + /** + * Create a {@link SslStoreProvider} if the appropriate SSL properties are configured. + * @param ssl the SSL properties + * @return a {@code SslStoreProvider} or {@code null} + */ + public static SslStoreProvider from(Ssl ssl) { + if (ssl != null && ssl.isEnabled()) { + if (ssl.getCertificate() != null && ssl.getCertificatePrivateKey() != null) { + return new CertificateFileSslStoreProvider(ssl); + } + } + return null; + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/CertificateParser.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/CertificateParser.java new file mode 100644 index 000000000000..11867b095fbe --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/CertificateParser.java @@ -0,0 +1,109 @@ +/* + * Copyright 2012-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.boot.web.server; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.springframework.util.Base64Utils; +import org.springframework.util.FileCopyUtils; +import org.springframework.util.ResourceUtils; + +/** + * Parser for X.509 certificates in PEM format. + * + * @author Scott Frederick + * @author Phillip Webb + */ +final class CertificateParser { + + private static final String HEADER = "-+BEGIN\\s+.*CERTIFICATE[^-]*-+(?:\\s|\\r|\\n)+"; + + private static final String BASE64_TEXT = "([a-z0-9+/=\\r\\n]+)"; + + private static final String FOOTER = "-+END\\s+.*CERTIFICATE[^-]*-+"; + + private static final Pattern PATTERN = Pattern.compile(HEADER + BASE64_TEXT + FOOTER, Pattern.CASE_INSENSITIVE); + + private CertificateParser() { + } + + /** + * Load certificates from the specified resource. + * @param path the certificate to parse + * @return the parsed certificates + */ + static X509Certificate[] parse(String path) { + CertificateFactory factory = getCertificateFactory(); + List certificates = new ArrayList<>(); + readCertificates(path, factory, certificates::add); + return certificates.toArray(new X509Certificate[0]); + } + + private static CertificateFactory getCertificateFactory() { + try { + return CertificateFactory.getInstance("X.509"); + } + catch (CertificateException ex) { + throw new IllegalStateException("Unable to get X.509 certificate factory", ex); + } + } + + private static void readCertificates(String resource, CertificateFactory factory, + Consumer consumer) { + try { + String text = readText(resource); + Matcher matcher = PATTERN.matcher(text); + while (matcher.find()) { + String encodedText = matcher.group(1); + byte[] decodedBytes = decodeBase64(encodedText); + ByteArrayInputStream inputStream = new ByteArrayInputStream(decodedBytes); + while (inputStream.available() > 0) { + consumer.accept((X509Certificate) factory.generateCertificate(inputStream)); + } + } + } + catch (CertificateException | IOException ex) { + throw new IllegalStateException("Error reading certificate from '" + resource + "' : " + ex.getMessage(), + ex); + } + } + + private static String readText(String resource) throws IOException { + URL url = ResourceUtils.getURL(resource); + try (Reader reader = new InputStreamReader(url.openStream())) { + return FileCopyUtils.copyToString(reader); + } + } + + private static byte[] decodeBase64(String content) { + byte[] bytes = content.replaceAll("\r", "").replaceAll("\n", "").getBytes(); + return Base64Utils.decode(bytes); + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/LocalServerPort.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/LocalServerPort.java index 07d2e2893c81..c522d48d0afc 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/LocalServerPort.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/LocalServerPort.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -28,6 +28,8 @@ * Annotation at the field or method/constructor parameter level that injects the HTTP * port that got allocated at runtime. Provides a convenient alternative for * @Value("${local.server.port}"). + * @deprecated since 2.7.0 for removal in 2.9.0 in favor or + * {@code org.springframework.boot.test.web.server.LocalServerPort} * * @author Anand Shah * @author Stephane Nicoll @@ -37,6 +39,7 @@ @Retention(RetentionPolicy.RUNTIME) @Documented @Value("${local.server.port}") +@Deprecated public @interface LocalServerPort { } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PrivateKeyParser.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PrivateKeyParser.java new file mode 100644 index 000000000000..924653d12528 --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PrivateKeyParser.java @@ -0,0 +1,149 @@ +/* + * Copyright 2012-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.boot.web.server; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import java.security.GeneralSecurityException; +import java.security.KeyFactory; +import java.security.PrivateKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.springframework.util.Base64Utils; +import org.springframework.util.FileCopyUtils; +import org.springframework.util.ResourceUtils; + +/** + * Parser for PKCS private key files in PEM format. + * + * @author Scott Frederick + * @author Phillip Webb + */ +final class PrivateKeyParser { + + private static final String PKCS1_HEADER = "-+BEGIN\\s+RSA\\s+PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+"; + + private static final String PKCS1_FOOTER = "-+END\\s+RSA\\s+PRIVATE\\s+KEY[^-]*-+"; + + private static final String PKCS8_FOOTER = "-+END\\s+PRIVATE\\s+KEY[^-]*-+"; + + private static final String PKCS8_HEADER = "-+BEGIN\\s+PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+"; + + private static final String BASE64_TEXT = "([a-z0-9+/=\\r\\n]+)"; + + private static final Pattern PKCS1_PATTERN = Pattern.compile(PKCS1_HEADER + BASE64_TEXT + PKCS1_FOOTER, + Pattern.CASE_INSENSITIVE); + + private static final Pattern PKCS8_KEY_PATTERN = Pattern.compile(PKCS8_HEADER + BASE64_TEXT + PKCS8_FOOTER, + Pattern.CASE_INSENSITIVE); + + private PrivateKeyParser() { + } + + /** + * Load a private key from the specified resource. + * @param resource the private key to parse + * @return the parsed private key + */ + static PrivateKey parse(String resource) { + try { + String text = readText(resource); + Matcher matcher = PKCS1_PATTERN.matcher(text); + if (matcher.find()) { + return parsePkcs1(decodeBase64(matcher.group(1))); + } + matcher = PKCS8_KEY_PATTERN.matcher(text); + if (matcher.find()) { + return parsePkcs8(decodeBase64(matcher.group(1))); + } + throw new IllegalStateException("Unrecognized private key format in " + resource); + } + catch (GeneralSecurityException | IOException ex) { + throw new IllegalStateException("Error loading private key file " + resource, ex); + } + } + + private static PrivateKey parsePkcs1(byte[] privateKeyBytes) throws GeneralSecurityException { + byte[] pkcs8Bytes = convertPkcs1ToPkcs8(privateKeyBytes); + return parsePkcs8(pkcs8Bytes); + } + + private static byte[] convertPkcs1ToPkcs8(byte[] pkcs1) { + try { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + int pkcs1Length = pkcs1.length; + int totalLength = pkcs1Length + 22; + // Sequence + total length + result.write(bytes(0x30, 0x82)); + result.write((totalLength >> 8) & 0xff); + result.write(totalLength & 0xff); + // Integer (0) + result.write(bytes(0x02, 0x01, 0x00)); + // Sequence: 1.2.840.113549.1.1.1, NULL + result.write( + bytes(0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00)); + // Octet string + length + result.write(bytes(0x04, 0x82)); + result.write((pkcs1Length >> 8) & 0xff); + result.write(pkcs1Length & 0xff); + // PKCS1 + result.write(pkcs1); + return result.toByteArray(); + } + catch (IOException ex) { + throw new IllegalStateException(ex); + } + } + + private static byte[] bytes(int... elements) { + byte[] result = new byte[elements.length]; + for (int i = 0; i < elements.length; i++) { + result[i] = (byte) elements[i]; + } + return result; + } + + private static PrivateKey parsePkcs8(byte[] privateKeyBytes) throws GeneralSecurityException { + try { + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + return keyFactory.generatePrivate(keySpec); + } + catch (InvalidKeySpecException ex) { + throw new IllegalArgumentException("Unexpected key format", ex); + } + } + + private static String readText(String resource) throws IOException { + URL url = ResourceUtils.getURL(resource); + try (Reader reader = new InputStreamReader(url.openStream())) { + return FileCopyUtils.copyToString(reader); + } + } + + private static byte[] decodeBase64(String content) { + byte[] contentBytes = content.replaceAll("\r", "").replaceAll("\n", "").getBytes(); + return Base64Utils.decode(contentBytes); + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Ssl.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Ssl.java index 8d1da04391e3..af4400717c7c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Ssl.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Ssl.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -22,6 +22,7 @@ * @author Andy Wilkinson * @author Vladimir Tsanev * @author Stephane Nicoll + * @author Scott Frederick * @since 2.0.0 */ public class Ssl { @@ -54,6 +55,14 @@ public class Ssl { private String trustStoreProvider; + private String certificate; + + private String certificatePrivateKey; + + private String trustCertificate; + + private String trustCertificatePrivateKey; + private String protocol = "TLS"; /** @@ -226,6 +235,54 @@ public void setTrustStoreProvider(String trustStoreProvider) { this.trustStoreProvider = trustStoreProvider; } + /** + * Return the location of the certificate in PEM format. + * @return the certificate location + */ + public String getCertificate() { + return this.certificate; + } + + public void setCertificate(String certificate) { + this.certificate = certificate; + } + + /** + * Return the location of the private key for the certificate in PEM format. + * @return the location of the certificate private key + */ + public String getCertificatePrivateKey() { + return this.certificatePrivateKey; + } + + public void setCertificatePrivateKey(String certificatePrivateKey) { + this.certificatePrivateKey = certificatePrivateKey; + } + + /** + * Return the location of the trust certificate authority chain in PEM format. + * @return the location of the trust certificate + */ + public String getTrustCertificate() { + return this.trustCertificate; + } + + public void setTrustCertificate(String trustCertificate) { + this.trustCertificate = trustCertificate; + } + + /** + * Return the location of the private key for the trust certificate in PEM format. + * @return the location of the trust certificate private key + */ + public String getTrustCertificatePrivateKey() { + return this.trustCertificatePrivateKey; + } + + public void setTrustCertificatePrivateKey(String trustCertificatePrivateKey) { + this.trustCertificatePrivateKey = trustCertificatePrivateKey; + } + /** * Return the SSL protocol to use. * @return the SSL protocol diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java index 9da658ccc9bd..d69f67280b0e 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java @@ -36,9 +36,11 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.Scope; import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.boot.WebApplicationType; import org.springframework.boot.availability.AvailabilityChangeEvent; import org.springframework.boot.availability.ReadinessState; import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext; +import org.springframework.boot.web.context.MissingWebServerFactoryBeanException; import org.springframework.boot.web.context.WebServerGracefulShutdownLifecycle; import org.springframework.boot.web.server.WebServer; import org.springframework.boot.web.servlet.FilterRegistrationBean; @@ -206,8 +208,8 @@ protected ServletWebServerFactory getWebServerFactory() { // Use bean names so that we don't consider the hierarchy String[] beanNames = getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class); if (beanNames.length == 0) { - throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing " - + "ServletWebServerFactory bean."); + throw new MissingWebServerFactoryBeanException(getClass(), ServletWebServerFactory.class, + WebApplicationType.SERVLET); } if (beanNames.length > 1) { throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple " diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/ServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/ServletWebServerFactory.java index b1bea96c44fa..062148af6a95 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/ServletWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/ServletWebServerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -17,6 +17,7 @@ package org.springframework.boot.web.servlet.server; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.WebServerFactory; import org.springframework.boot.web.servlet.ServletContextInitializer; /** @@ -27,7 +28,7 @@ * @see WebServer */ @FunctionalInterface -public interface ServletWebServerFactory { +public interface ServletWebServerFactory extends WebServerFactory { /** * Gets a new fully configured but paused {@link WebServer} instance. Clients should diff --git a/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories index 95f7013b783b..937fc54c794c 100644 --- a/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories @@ -74,6 +74,7 @@ org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFa org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer,\ org.springframework.boot.diagnostics.analyzer.PatternParseFailureAnalyzer,\ org.springframework.boot.liquibase.LiquibaseChangelogMissingFailureAnalyzer,\ +org.springframework.boot.web.context.MissingWebServerFactoryBeanFailureAnalyzer,\ org.springframework.boot.web.embedded.tomcat.ConnectorStartFailureAnalyzer # Failure Analysis Reporters diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ExitCodeGeneratorsTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ExitCodeGeneratorsTests.java index 9a81e7162653..051278528375 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ExitCodeGeneratorsTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ExitCodeGeneratorsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -21,10 +21,13 @@ import org.junit.jupiter.api.Test; +import org.springframework.core.Ordered; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.withSettings; /** * Tests for {@link ExitCodeGenerators}. @@ -62,18 +65,9 @@ void getExitCodeWhenGeneratorThrowsShouldReturnOne() { } @Test - void getExitCodeWhenAllNegativeShouldReturnLowestValue() { - ExitCodeGenerators generators = new ExitCodeGenerators(); - generators.add(mockGenerator(-1)); - generators.add(mockGenerator(-3)); - generators.add(mockGenerator(-2)); - assertThat(generators.getExitCode()).isEqualTo(-3); - } - - @Test - void getExitCodeWhenAllPositiveShouldReturnHighestValue() { + void getExitCodeWithUnorderedGeneratorsReturnsFirstNonZeroExitCode() { ExitCodeGenerators generators = new ExitCodeGenerators(); - generators.add(mockGenerator(1)); + generators.add(mockGenerator(0)); generators.add(mockGenerator(3)); generators.add(mockGenerator(2)); assertThat(generators.getExitCode()).isEqualTo(3); @@ -89,12 +83,29 @@ void getExitCodeWhenUsingExitCodeExceptionMapperShouldCallMapper() { assertThat(generators.getExitCode()).isEqualTo(2); } + @Test + void getExitCodeWithOrderedGeneratorsReturnsFirstNonZeroExitCode() { + ExitCodeGenerators generators = new ExitCodeGenerators(); + generators.add(orderedMockGenerator(0, 1)); + generators.add(orderedMockGenerator(1, 3)); + generators.add(orderedMockGenerator(2, 2)); + generators.add(mockGenerator(3)); + assertThat(generators.getExitCode()).isEqualTo(2); + } + private ExitCodeGenerator mockGenerator(int exitCode) { ExitCodeGenerator generator = mock(ExitCodeGenerator.class); given(generator.getExitCode()).willReturn(exitCode); return generator; } + private ExitCodeGenerator orderedMockGenerator(int exitCode, int order) { + ExitCodeGenerator generator = mock(ExitCodeGenerator.class, withSettings().extraInterfaces(Ordered.class)); + given(generator.getExitCode()).willReturn(exitCode); + given(((Ordered) generator).getOrder()).willReturn(order); + return generator; + } + private ExitCodeExceptionMapper mockMapper(Class exceptionType, int exitCode) { return (exception) -> { if (exceptionType.isInstance(exception)) { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringBootVersionTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringBootVersionTests.java index 9e6995b3b557..887413c25ca4 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringBootVersionTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringBootVersionTests.java @@ -31,7 +31,7 @@ * * @author Andy Wilkinson */ -public class SpringBootVersionTests { +class SpringBootVersionTests { @Test void getVersionShouldReturnVersionMatchingGradleProperties() throws IOException { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesBeanTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesBeanTests.java index a11250b39d19..3fad65e03a42 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesBeanTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesBeanTests.java @@ -78,6 +78,15 @@ void getAllReturnsAll() { } } + @Test + void getAllDoesNotFindABeanDeclaredInAStaticBeanMethodOnAConfigurationAndConfigurationPropertiesAnnotatedClass() { + try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + StaticBeanMethodConfiguration.class)) { + Map all = ConfigurationPropertiesBean.getAll(context); + assertThat(all).containsOnlyKeys("configurationPropertiesBeanTests.StaticBeanMethodConfiguration"); + } + } + @Test void getAllWhenHasBadBeanDoesNotFail() { try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( @@ -604,6 +613,18 @@ class Inner { class ParameterizedConstructorInner { ParameterizedConstructorInner(Integer age) { + + } + + } + + @Configuration(proxyBeanMethods = false) + @ConfigurationProperties + static class StaticBeanMethodConfiguration { + + @Bean + static String stringBean() { + return "example"; } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/BeanCurrentlyInCreationFailureAnalyzerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/BeanCurrentlyInCreationFailureAnalyzerTests.java index 3324acb57118..ba6f4f6e5ca6 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/BeanCurrentlyInCreationFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/BeanCurrentlyInCreationFailureAnalyzerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -43,10 +43,14 @@ * Tests for {@link BeanCurrentlyInCreationFailureAnalyzer}. * * @author Andy Wilkinson + * @author Scott Frederick */ class BeanCurrentlyInCreationFailureAnalyzerTests { - private final BeanCurrentlyInCreationFailureAnalyzer analyzer = new BeanCurrentlyInCreationFailureAnalyzer(); + private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + + private final BeanCurrentlyInCreationFailureAnalyzer analyzer = new BeanCurrentlyInCreationFailureAnalyzer( + this.context.getBeanFactory()); @Test void cyclicBeanMethods() throws IOException { @@ -131,13 +135,13 @@ void cycleWithAnUnknownStartIsNotAnalyzed() { } @Test - void cycleWithCircularReferencesAllowed() throws IOException { + void cycleWithCircularReferencesAllowed() { FailureAnalysis analysis = performAnalysis(CyclicBeanMethodsConfiguration.class, true); assertThat(analysis.getAction()).contains("Despite circular references being allowed"); } @Test - void cycleWithCircularReferencesProhibited() throws IOException { + void cycleWithCircularReferencesProhibited() { FailureAnalysis analysis = performAnalysis(CyclicBeanMethodsConfiguration.class, false); assertThat(analysis.getAction()).contains("As a last resort"); } @@ -159,13 +163,12 @@ private FailureAnalysis performAnalysis(Class configuration, boolean allowCir } private Exception createFailure(Class configuration, boolean allowCircularReferences) { - try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) { - context.register(configuration); - AbstractAutowireCapableBeanFactory beanFactory = (AbstractAutowireCapableBeanFactory) context + try { + this.context.register(configuration); + AbstractAutowireCapableBeanFactory beanFactory = (AbstractAutowireCapableBeanFactory) this.context .getBeanFactory(); - this.analyzer.setBeanFactory(beanFactory); beanFactory.setAllowCircularReferences(allowCircularReferences); - context.refresh(); + this.context.refresh(); fail("Expected failure did not occur"); return null; } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/InvalidConfigurationPropertyValueFailureAnalyzerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/InvalidConfigurationPropertyValueFailureAnalyzerTests.java index 45d47f6e5abc..f8cf1a3e2be7 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/InvalidConfigurationPropertyValueFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/InvalidConfigurationPropertyValueFailureAnalyzerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -34,6 +34,7 @@ * Tests for {@link InvalidConfigurationPropertyValueFailureAnalyzer}. * * @author Stephane Nicoll + * @author Scott Frederick */ class InvalidConfigurationPropertyValueFailureAnalyzerTests { @@ -43,7 +44,7 @@ class InvalidConfigurationPropertyValueFailureAnalyzerTests { void analysisWithNullEnvironment() { InvalidConfigurationPropertyValueException failure = new InvalidConfigurationPropertyValueException( "test.property", "invalid", "This is not valid."); - FailureAnalysis analysis = new InvalidConfigurationPropertyValueFailureAnalyzer().analyze(failure); + FailureAnalysis analysis = new InvalidConfigurationPropertyValueFailureAnalyzer(null).analyze(failure); assertThat(analysis).isNull(); } @@ -106,8 +107,8 @@ private void assertCommonParts(InvalidConfigurationPropertyValueException failur } private FailureAnalysis performAnalysis(InvalidConfigurationPropertyValueException failure) { - InvalidConfigurationPropertyValueFailureAnalyzer analyzer = new InvalidConfigurationPropertyValueFailureAnalyzer(); - analyzer.setEnvironment(this.environment); + InvalidConfigurationPropertyValueFailureAnalyzer analyzer = new InvalidConfigurationPropertyValueFailureAnalyzer( + this.environment); return analyzer.analyze(failure); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/MutuallyExclusiveConfigurationPropertiesFailureAnalyzerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/MutuallyExclusiveConfigurationPropertiesFailureAnalyzerTests.java index 04e373a18c41..a81645e36f9c 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/MutuallyExclusiveConfigurationPropertiesFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/MutuallyExclusiveConfigurationPropertiesFailureAnalyzerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -39,6 +39,7 @@ * Tests for {@link MutuallyExclusiveConfigurationPropertiesFailureAnalyzer}. * * @author Andy Wilkinson + * @author Scott Frederick */ class MutuallyExclusiveConfigurationPropertiesFailureAnalyzerTests { @@ -49,7 +50,7 @@ void analyzeWhenEnvironmentIsNullShouldReturnNull() { MutuallyExclusiveConfigurationPropertiesException failure = new MutuallyExclusiveConfigurationPropertiesException( new HashSet<>(Arrays.asList("com.example.a", "com.example.b")), new HashSet<>(Arrays.asList("com.example.a", "com.example.b"))); - FailureAnalysis failureAnalysis = new MutuallyExclusiveConfigurationPropertiesFailureAnalyzer() + FailureAnalysis failureAnalysis = new MutuallyExclusiveConfigurationPropertiesFailureAnalyzer(null) .analyze(failure); assertThat(failureAnalysis).isNull(); } @@ -112,8 +113,8 @@ void analyzeWhenPropertyIsInMultiplePropertySourcesShouldListEachSourceInAnalysi } private FailureAnalysis performAnalysis(MutuallyExclusiveConfigurationPropertiesException failure) { - MutuallyExclusiveConfigurationPropertiesFailureAnalyzer analyzer = new MutuallyExclusiveConfigurationPropertiesFailureAnalyzer(); - analyzer.setEnvironment(this.environment); + MutuallyExclusiveConfigurationPropertiesFailureAnalyzer analyzer = new MutuallyExclusiveConfigurationPropertiesFailureAnalyzer( + this.environment); return analyzer.analyze(failure); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzerTests.java index aebbab4bbbad..b14fcaa76dd4 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -36,10 +36,14 @@ * Tests for {@link NoUniqueBeanDefinitionFailureAnalyzer}. * * @author Andy Wilkinson + * @author Scott Frederick */ class NoUniqueBeanDefinitionFailureAnalyzerTests { - private final NoUniqueBeanDefinitionFailureAnalyzer analyzer = new NoUniqueBeanDefinitionFailureAnalyzer(); + private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + + private final NoUniqueBeanDefinitionFailureAnalyzer analyzer = new NoUniqueBeanDefinitionFailureAnalyzer( + this.context.getBeanFactory()); @Test void failureAnalysisForFieldConsumer() { @@ -90,18 +94,15 @@ void failureAnalysisForObjectProviderConstructorConsumer() { } private BeanCreationException createFailure(Class consumer) { - try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) { - context.register(DuplicateBeansProducer.class, consumer); - context.setParent(new AnnotationConfigApplicationContext(ParentProducer.class)); - try { - context.refresh(); - } - catch (BeanCreationException ex) { - this.analyzer.setBeanFactory(context.getBeanFactory()); - return ex; - } - return null; + this.context.register(DuplicateBeansProducer.class, consumer); + this.context.setParent(new AnnotationConfigApplicationContext(ParentProducer.class)); + try { + this.context.refresh(); + } + catch (BeanCreationException ex) { + return ex; } + return null; } private FailureAnalysis analyzeFailure(BeanCreationException failure) { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/context/LocalRSocketServerPortTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/context/LocalRSocketServerPortTests.java index 452a7d8e1d3e..55852ba1f1ef 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/context/LocalRSocketServerPortTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/context/LocalRSocketServerPortTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -32,6 +32,7 @@ * @author Verónica Vásquez * @author Eddú Meléndez */ +@Deprecated @ExtendWith(SpringExtension.class) @TestPropertySource(properties = "local.rsocket.server.port=8181") class LocalRSocketServerPortTests { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactoryTests.java index 0a79bea42861..4c739922fd98 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactoryTests.java @@ -64,6 +64,7 @@ * @author Brian Clozel * @author Leo Li * @author Chris Bono + * @author Scott Frederick */ class NettyRSocketServerFactoryTests { @@ -166,6 +167,30 @@ void websocketTransportBasicSslFromFileSystem() { testBasicSslWithKeyStore("src/test/resources/test.jks", "password", Transport.WEBSOCKET); } + @Test + void tcpTransportBasicSslCertificateFromClassPath() { + testBasicSslWithPemCertificate("classpath:test-cert.pem", "classpath:test-key.pem", "classpath:test-cert.pem", + Transport.TCP); + } + + @Test + void tcpTransportBasicSslCertificateFromFileSystem() { + testBasicSslWithPemCertificate("src/test/resources/test-cert.pem", "src/test/resources/test-key.pem", + "src/test/resources/test-cert.pem", Transport.TCP); + } + + @Test + void websocketTransportBasicSslCertificateFromClassPath() { + testBasicSslWithPemCertificate("classpath:test-cert.pem", "classpath:test-key.pem", "classpath:test-cert.pem", + Transport.WEBSOCKET); + } + + @Test + void websocketTransportBasicSslCertificateFromFileSystem() { + testBasicSslWithPemCertificate("src/test/resources/test-cert.pem", "src/test/resources/test-key.pem", + "src/test/resources/test-cert.pem", Transport.WEBSOCKET); + } + private void checkEchoRequest() { String payload = "test payload"; Mono response = this.requester.route("test").data(payload).retrieveMono(String.class); @@ -186,6 +211,23 @@ private void testBasicSslWithKeyStore(String keyStore, String keyPassword, Trans checkEchoRequest(); } + private void testBasicSslWithPemCertificate(String certificate, String certificatePrivateKey, + String trustCertificate, Transport transport) { + NettyRSocketServerFactory factory = getFactory(); + factory.setTransport(transport); + Ssl ssl = new Ssl(); + ssl.setCertificate(certificate); + ssl.setCertificatePrivateKey(certificatePrivateKey); + ssl.setTrustCertificate(trustCertificate); + ssl.setKeyStorePassword(""); + factory.setSsl(ssl); + this.server = factory.create(new EchoRequestResponseAcceptor()); + this.server.start(); + this.requester = (transport == Transport.TCP) ? createSecureRSocketTcpClient() + : createSecureRSocketWebSocketClient(); + checkEchoRequest(); + } + @Test void tcpTransportSslRejectsInsecureClient() { NettyRSocketServerFactory factory = getFactory(); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzerTests.java new file mode 100644 index 000000000000..fb30be29caf4 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzerTests.java @@ -0,0 +1,75 @@ +/* + * Copyright 2012-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.boot.web.context; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.diagnostics.FailureAnalysis; +import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext; +import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; +import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.context.ApplicationContextException; +import org.springframework.context.ConfigurableApplicationContext; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link MissingWebServerFactoryBeanFailureAnalyzer}. + * + * @author Guirong Hu + * @author Andy Wilkinson + */ +class MissingWebServerFactoryBeanFailureAnalyzerTests { + + @Test + void missingServletWebServerFactoryBeanFailure() { + ApplicationContextException failure = createFailure(new ServletWebServerApplicationContext()); + assertThat(failure).isNotNull(); + FailureAnalysis analysis = new MissingWebServerFactoryBeanFailureAnalyzer().analyze(failure); + assertThat(analysis).isNotNull(); + assertThat(analysis.getDescription()).isEqualTo("Web application could not be started as there was no " + + ServletWebServerFactory.class.getName() + " bean defined in the context."); + assertThat(analysis.getAction()).isEqualTo( + "Check your application's dependencies for a supported servlet web server.\nCheck the configured web " + + "application type."); + } + + @Test + void missingReactiveWebServerFactoryBeanFailure() { + ApplicationContextException failure = createFailure(new ReactiveWebServerApplicationContext()); + FailureAnalysis analysis = new MissingWebServerFactoryBeanFailureAnalyzer().analyze(failure); + assertThat(analysis).isNotNull(); + assertThat(analysis.getDescription()).isEqualTo("Web application could not be started as there was no " + + ReactiveWebServerFactory.class.getName() + " bean defined in the context."); + assertThat(analysis.getAction()).isEqualTo( + "Check your application's dependencies for a supported reactive web server.\nCheck the configured web " + + "application type."); + } + + private ApplicationContextException createFailure(ConfigurableApplicationContext context) { + try { + context.refresh(); + context.close(); + return null; + } + catch (ApplicationContextException ex) { + return ex; + } + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java index d467117edc41..dc103519a9ea 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java @@ -27,6 +27,7 @@ import java.util.HashMap; import java.util.Locale; import java.util.Map; +import java.util.Properties; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicReference; @@ -80,6 +81,8 @@ import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory; import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactoryTests; import org.springframework.core.io.ByteArrayResource; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.support.PropertiesLoaderUtils; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -404,13 +407,15 @@ protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) { } @Test - void defaultLocaleCharsetMappingsAreOverridden() { + void defaultLocaleCharsetMappingsAreOverridden() throws IOException { TomcatServletWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(); // override defaults, see org.apache.catalina.util.CharsetMapperDefault.properties - assertThat(getCharset(Locale.ENGLISH)).isEqualTo(StandardCharsets.UTF_8); - assertThat(getCharset(Locale.FRENCH)).isEqualTo(StandardCharsets.UTF_8); - assertThat(getCharset(Locale.JAPANESE)).isEqualTo(StandardCharsets.UTF_8); + Properties charsetMapperDefault = PropertiesLoaderUtils + .loadProperties(new ClassPathResource("CharsetMapperDefault.properties", CharsetMapper.class)); + for (String language : charsetMapperDefault.stringPropertyNames()) { + assertThat(getCharset(new Locale(language))).isEqualTo(StandardCharsets.UTF_8); + } } @Test diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContextTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContextTests.java index 24ff9da399ab..13ae884265cc 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContextTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContextTests.java @@ -61,7 +61,7 @@ void cleanUp() { void whenThereIsNoWebServerFactoryBeanThenContextRefreshWillFail() { assertThatExceptionOfType(ApplicationContextException.class).isThrownBy(() -> this.context.refresh()) .withMessageContaining( - "Unable to start ReactiveWebApplicationContext due to missing ReactiveWebServerFactory bean"); + "Unable to start ReactiveWebServerApplicationContext due to missing ReactiveWebServerFactory bean"); } @Test diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java index e694b1c89dcd..96b9d93fb153 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java @@ -86,6 +86,7 @@ * Base for testing classes that extends {@link AbstractReactiveWebServerFactory}. * * @author Brian Clozel + * @author Scott Frederick */ public abstract class AbstractReactiveWebServerFactoryTests { @@ -215,7 +216,7 @@ void sslWantsClientAuthenticationSucceedsWithClientCertificate() throws Exceptio ssl.setKeyPassword("password"); ssl.setKeyStorePassword("secret"); ssl.setTrustStore("classpath:test.jks"); - testClientAuthSuccess(ssl, buildTrustAllSslWithClientKeyConnector()); + testClientAuthSuccess(ssl, buildTrustAllSslWithClientKeyConnector("test.jks", "password")); } @Test @@ -229,14 +230,15 @@ void sslWantsClientAuthenticationSucceedsWithoutClientCertificate() { testClientAuthSuccess(ssl, buildTrustAllSslConnector()); } - protected ReactorClientHttpConnector buildTrustAllSslWithClientKeyConnector() throws Exception { + protected ReactorClientHttpConnector buildTrustAllSslWithClientKeyConnector(String keyStoreFile, + String keyStorePassword) throws Exception { KeyStore clientKeyStore = KeyStore.getInstance(KeyStore.getDefaultType()); - try (InputStream stream = new FileInputStream("src/test/resources/test.jks")) { + try (InputStream stream = new FileInputStream("src/test/resources/" + keyStoreFile)) { clientKeyStore.load(stream, "secret".toCharArray()); } KeyManagerFactory clientKeyManagerFactory = KeyManagerFactory .getInstance(KeyManagerFactory.getDefaultAlgorithm()); - clientKeyManagerFactory.init(clientKeyStore, "password".toCharArray()); + clientKeyManagerFactory.init(clientKeyStore, keyStorePassword.toCharArray()); Http11SslContextSpec sslContextSpec = Http11SslContextSpec.forClient() .configure((builder) -> builder.sslProvider(SslProvider.JDK) @@ -265,7 +267,7 @@ void sslNeedsClientAuthenticationSucceedsWithClientCertificate() throws Exceptio ssl.setKeyStorePassword("secret"); ssl.setKeyPassword("password"); ssl.setTrustStore("classpath:test.jks"); - testClientAuthSuccess(ssl, buildTrustAllSslWithClientKeyConnector()); + testClientAuthSuccess(ssl, buildTrustAllSslWithClientKeyConnector("test.jks", "password")); } @Test @@ -279,6 +281,17 @@ void sslNeedsClientAuthenticationFailsWithoutClientCertificate() { testClientAuthFailure(ssl, buildTrustAllSslConnector()); } + @Test + void sslWithPemCertificates() throws Exception { + Ssl ssl = new Ssl(); + ssl.setClientAuth(Ssl.ClientAuth.NEED); + ssl.setCertificate("classpath:test-cert.pem"); + ssl.setCertificatePrivateKey("classpath:test-key.pem"); + ssl.setTrustCertificate("classpath:test-cert.pem"); + ssl.setKeyStorePassword("secret"); + testClientAuthSuccess(ssl, buildTrustAllSslWithClientKeyConnector("test.p12", "secret")); + } + protected void testClientAuthFailure(Ssl sslConfiguration, ReactorClientHttpConnector clientConnector) { AbstractReactiveWebServerFactory factory = getFactory(); factory.setSsl(sslConfiguration); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CertificateFileSslStoreProviderTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CertificateFileSslStoreProviderTests.java new file mode 100644 index 000000000000..8f0fcdd6626e --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CertificateFileSslStoreProviderTests.java @@ -0,0 +1,133 @@ +/* + * Copyright 2012-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.boot.web.server; + +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link CertificateFileSslStoreProvider}. + * + * @author Scott Frederick + */ +class CertificateFileSslStoreProviderTests { + + @Test + void fromSslWhenNullReturnsNull() { + assertThat(CertificateFileSslStoreProvider.from(null)).isNull(); + } + + @Test + void fromSslWhenDisabledReturnsNull() { + assertThat(CertificateFileSslStoreProvider.from(new Ssl())).isNull(); + } + + @Test + void fromSslWithCertAndKeyReturnsStoreProvider() throws Exception { + Ssl ssl = new Ssl(); + ssl.setEnabled(true); + ssl.setCertificate("classpath:test-cert.pem"); + ssl.setCertificatePrivateKey("classpath:test-key.pem"); + SslStoreProvider storeProvider = CertificateFileSslStoreProvider.from(ssl); + assertThat(storeProvider).isNotNull(); + assertStoreContainsCertAndKey(storeProvider.getKeyStore(), KeyStore.getDefaultType(), "spring-boot-web"); + assertThat(storeProvider.getTrustStore()).isNull(); + } + + @Test + void fromSslWithCertAndKeyAndTrustCertReturnsStoreProvider() throws Exception { + Ssl ssl = new Ssl(); + ssl.setEnabled(true); + ssl.setCertificate("classpath:test-cert.pem"); + ssl.setCertificatePrivateKey("classpath:test-key.pem"); + ssl.setTrustCertificate("classpath:test-cert.pem"); + SslStoreProvider storeProvider = CertificateFileSslStoreProvider.from(ssl); + assertThat(storeProvider).isNotNull(); + assertStoreContainsCertAndKey(storeProvider.getKeyStore(), KeyStore.getDefaultType(), "spring-boot-web"); + assertStoreContainsCert(storeProvider.getTrustStore(), KeyStore.getDefaultType(), "spring-boot-web-0"); + } + + @Test + void fromSslWithCertAndKeyAndTrustCertAndTrustKeyReturnsStoreProvider() throws Exception { + Ssl ssl = new Ssl(); + ssl.setEnabled(true); + ssl.setCertificate("classpath:test-cert.pem"); + ssl.setCertificatePrivateKey("classpath:test-key.pem"); + ssl.setTrustCertificate("classpath:test-cert.pem"); + ssl.setTrustCertificatePrivateKey("classpath:test-key.pem"); + SslStoreProvider storeProvider = CertificateFileSslStoreProvider.from(ssl); + assertThat(storeProvider).isNotNull(); + assertStoreContainsCertAndKey(storeProvider.getKeyStore(), KeyStore.getDefaultType(), "spring-boot-web"); + assertStoreContainsCertAndKey(storeProvider.getTrustStore(), KeyStore.getDefaultType(), "spring-boot-web"); + } + + @Test + void fromSslWithKeyAliasReturnsStoreProvider() throws Exception { + Ssl ssl = new Ssl(); + ssl.setEnabled(true); + ssl.setKeyAlias("test-alias"); + ssl.setCertificate("classpath:test-cert.pem"); + ssl.setCertificatePrivateKey("classpath:test-key.pem"); + ssl.setTrustCertificate("classpath:test-cert.pem"); + ssl.setTrustCertificatePrivateKey("classpath:test-key.pem"); + SslStoreProvider storeProvider = CertificateFileSslStoreProvider.from(ssl); + assertThat(storeProvider).isNotNull(); + assertStoreContainsCertAndKey(storeProvider.getKeyStore(), KeyStore.getDefaultType(), "test-alias"); + assertStoreContainsCertAndKey(storeProvider.getTrustStore(), KeyStore.getDefaultType(), "test-alias"); + } + + @Test + void fromSslWithStoreTypeReturnsStoreProvider() throws Exception { + Ssl ssl = new Ssl(); + ssl.setEnabled(true); + ssl.setKeyStoreType("PKCS12"); + ssl.setTrustStoreType("PKCS12"); + ssl.setCertificate("classpath:test-cert.pem"); + ssl.setCertificatePrivateKey("classpath:test-key.pem"); + ssl.setTrustCertificate("classpath:test-cert.pem"); + ssl.setTrustCertificatePrivateKey("classpath:test-key.pem"); + SslStoreProvider storeProvider = CertificateFileSslStoreProvider.from(ssl); + assertThat(storeProvider).isNotNull(); + assertStoreContainsCertAndKey(storeProvider.getKeyStore(), "PKCS12", "spring-boot-web"); + assertStoreContainsCertAndKey(storeProvider.getTrustStore(), "PKCS12", "spring-boot-web"); + } + + private void assertStoreContainsCertAndKey(KeyStore keyStore, String keyStoreType, String keyAlias) + throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { + assertThat(keyStore).isNotNull(); + assertThat(keyStore.getType()).isEqualTo(keyStoreType); + assertThat(keyStore.containsAlias(keyAlias)).isTrue(); + assertThat(keyStore.getCertificate(keyAlias)).isNotNull(); + assertThat(keyStore.getKey(keyAlias, new char[] {})).isNotNull(); + } + + private void assertStoreContainsCert(KeyStore keyStore, String keyStoreType, String keyAlias) + throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { + assertThat(keyStore).isNotNull(); + assertThat(keyStore.getType()).isEqualTo(keyStoreType); + assertThat(keyStore.containsAlias(keyAlias)).isTrue(); + assertThat(keyStore.getCertificate(keyAlias)).isNotNull(); + assertThat(keyStore.getKey(keyAlias, new char[] {})).isNull(); + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CertificateParserTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CertificateParserTests.java new file mode 100644 index 000000000000..7107c1ae7b59 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CertificateParserTests.java @@ -0,0 +1,57 @@ +/* + * Copyright 2012-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.boot.web.server; + +import java.security.cert.X509Certificate; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; + +/** + * Tests for {@link CertificateParser}. + * + * @author Scott Frederick + */ +class CertificateParserTests { + + @Test + void parseCertificate() { + X509Certificate[] certificates = CertificateParser.parse("classpath:test-cert.pem"); + assertThat(certificates).isNotNull(); + assertThat(certificates.length).isEqualTo(1); + assertThat(certificates[0].getType()).isEqualTo("X.509"); + } + + @Test + void parseCertificateChain() { + X509Certificate[] certificates = CertificateParser.parse("classpath:test-cert-chain.pem"); + assertThat(certificates).isNotNull(); + assertThat(certificates.length).isEqualTo(2); + assertThat(certificates[0].getType()).isEqualTo("X.509"); + assertThat(certificates[1].getType()).isEqualTo("X.509"); + } + + @Test + void parseWithInvalidPathWillThrowException() { + String path = "file:///bad/path/cert.pem"; + assertThatIllegalStateException().isThrownBy(() -> CertificateParser.parse("file:///bad/path/cert.pem")) + .withMessageContaining(path); + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/LocalServerPortTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/LocalServerPortTests.java index da6fd5c2cc17..3c5004bc21bd 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/LocalServerPortTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/LocalServerPortTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -32,6 +32,7 @@ * @author Anand Shah * @author Phillip Webb */ +@Deprecated @ExtendWith(SpringExtension.class) @TestPropertySource(properties = "local.server.port=8181") class LocalServerPortTests { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/PrivateKeyParserTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/PrivateKeyParserTests.java new file mode 100644 index 000000000000..0a55581ea915 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/PrivateKeyParserTests.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-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.boot.web.server; + +import java.security.PrivateKey; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; + +/** + * Tests for {@link PrivateKeyParser}. + * + * @author Scott Frederick + */ +class PrivateKeyParserTests { + + @Test + void parsePkcs8KeyFile() { + PrivateKey privateKey = PrivateKeyParser.parse("classpath:test-key.pem"); + assertThat(privateKey).isNotNull(); + assertThat(privateKey.getFormat()).isEqualTo("PKCS#8"); + } + + @Test + void parseWithNonKeyFileWillThrowException() { + String path = "classpath:test-banner.txt"; + assertThatIllegalStateException().isThrownBy(() -> PrivateKeyParser.parse("file://" + path)) + .withMessageContaining(path); + } + + @Test + void parseWithInvalidPathWillThrowException() { + String path = "file:///bad/path/key.pem"; + assertThatIllegalStateException().isThrownBy(() -> PrivateKeyParser.parse(path)).withMessageContaining(path); + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactoryTests.java index 690b66a93f8a..321edb55cd3f 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactoryTests.java @@ -167,6 +167,7 @@ * @author Greg Turnquist * @author Andy Wilkinson * @author Raja Kolli + * @author Scott Frederick */ @ExtendWith(OutputCaptureExtension.class) public abstract class AbstractServletWebServerFactoryTests { @@ -559,6 +560,23 @@ void pkcs12KeyStoreAndTrustStore() throws Exception { assertThat(getResponse(getLocalUrl("https", "/test.txt"), requestFactory)).isEqualTo("test"); } + @Test + void pemKeyStoreAndTrustStore() throws Exception { + AbstractServletWebServerFactory factory = getFactory(); + addTestTxtFile(factory); + factory.setSsl(getSsl("classpath:test-cert.pem", "classpath:test-key.pem")); + this.webServer = factory.getWebServer(); + this.webServer.start(); + KeyStore keyStore = KeyStore.getInstance("pkcs12"); + loadStore(keyStore, new FileSystemResource("src/test/resources/test.p12")); + SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( + new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy()) + .loadKeyMaterial(keyStore, "secret".toCharArray()).build()); + HttpClient httpClient = this.httpClientBuilder.get().setSSLSocketFactory(socketFactory).build(); + HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); + assertThat(getResponse(getLocalUrl("https", "/test.txt"), requestFactory)).isEqualTo("test"); + } + @Test void sslNeedsClientAuthenticationSucceedsWithClientCertificate() throws Exception { AbstractServletWebServerFactory factory = getFactory(); @@ -710,6 +728,16 @@ private Ssl getSsl(ClientAuth clientAuth, String keyPassword, String keyAlias, S return ssl; } + private Ssl getSsl(String cert, String privateKey) { + Ssl ssl = new Ssl(); + ssl.setClientAuth(ClientAuth.NEED); + ssl.setCertificate(cert); + ssl.setCertificatePrivateKey(privateKey); + ssl.setTrustCertificate(cert); + ssl.setKeyStorePassword("secret"); + return ssl; + } + protected void testRestrictedSSLProtocolsAndCipherSuites(String[] protocols, String[] ciphers) throws Exception { AbstractServletWebServerFactory factory = getFactory(); factory.setSsl(getSsl(null, "password", "src/test/resources/restricted.jks", null, protocols, ciphers)); diff --git a/spring-boot-project/spring-boot/src/test/resources/test-cert-chain.pem b/spring-boot-project/spring-boot/src/test/resources/test-cert-chain.pem new file mode 100644 index 000000000000..df103772cfe2 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/test-cert-chain.pem @@ -0,0 +1,32 @@ +-----BEGIN TRUSTED CERTIFICATE----- +MIIClzCCAgACCQCPbjkRoMVEQDANBgkqhkiG9w0BAQUFADCBjzELMAkGA1UEBhMC +VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28x +DTALBgNVBAoMBFRlc3QxDTALBgNVBAsMBFRlc3QxFDASBgNVBAMMC2V4YW1wbGUu +Y29tMR8wHQYJKoZIhvcNAQkBFhB0ZXN0QGV4YW1wbGUuY29tMB4XDTIwMDMyNzIx +NTgwNFoXDTIxMDMyNzIxNTgwNFowgY8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApD +YWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ0wCwYDVQQKDARUZXN0 +MQ0wCwYDVQQLDARUZXN0MRQwEgYDVQQDDAtleGFtcGxlLmNvbTEfMB0GCSqGSIb3 +DQEJARYQdGVzdEBleGFtcGxlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +gYEA1YzixWEoyzrd20C2R1gjyPCoPfFLlG6UYTyT0tueNy6yjv6qbJ8lcZg7616O +3I9LuOHhZh9U+fCDCgPfiDdyJfDEW/P+dsOMFyMUXPrJPze2yPpOnvV8iJ5DM93u +fEVhCCyzLdYu0P2P3hU2W+T3/Im9DA7FOPA2vF1SrIJ2qtUCAwEAATANBgkqhkiG +9w0BAQUFAAOBgQBdShkwUv78vkn1jAdtfbB+7mpV9tufVdo29j7pmotTCz3ny5fc +zLEfeu6JPugAR71JYbc2CqGrMneSk1zT91EH6ohIz8OR5VNvzB7N7q65Ci7OFMPl +ly6k3rHpMCBtHoyNFhNVfPLxGJ9VlWFKLgIAbCmL4OIQm1l6Fr1MSM38Zw== +-----END TRUSTED CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICjzCCAfgCAQEwDQYJKoZIhvcNAQEFBQAwgY8xCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ0wCwYDVQQK +DARUZXN0MQ0wCwYDVQQLDARUZXN0MRQwEgYDVQQDDAtleGFtcGxlLmNvbTEfMB0G +CSqGSIb3DQEJARYQdGVzdEBleGFtcGxlLmNvbTAeFw0yMDAzMjcyMjAxNDZaFw0y +MTAzMjcyMjAxNDZaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5p +YTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwEVGVzdDENMAsGA1UE +CwwEVGVzdDEUMBIGA1UEAwwLZXhhbXBsZS5jb20xHzAdBgkqhkiG9w0BCQEWEHRl +c3RAZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM7kd2cj +F49wm1+OQ7Q5GE96cXueWNPr/Nwei71tf6G4BmE0B+suXHEvnLpHTj9pdX/ZzBIK +8jIZ/x8RnSduK/Ky+zm1QMYUWZtWCAgCW8WzgB69Cn/hQG8KSX3S9bqODuQAvP54 +GQJD7+4kVuNBGjFb4DaD4nvMmPtALSZf8ZCZAgMBAAEwDQYJKoZIhvcNAQEFBQAD +gYEAOn6X8+0VVlDjF+TvTgI0KIasA6nDm+KXe7LVtfvqWqQZH4qyd2uiwcDM3Aux +a/OsPdOw0j+NqFDBd3mSMhSVgfvXdK6j9WaxY1VGXyaidLARgvn63wfzgr857sQW +c8eSxbwEQxwlMvVxW6Os4VhCfUQr8VrBrvPa2zs+6IlK+Ug= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/spring-boot-project/spring-boot/src/test/resources/test-cert.pem b/spring-boot-project/spring-boot/src/test/resources/test-cert.pem new file mode 100644 index 000000000000..1e912b9f6399 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/test-cert.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICpDCCAYwCCQCDOqHKPjAhCTANBgkqhkiG9w0BAQUFADAUMRIwEAYDVQQDDAls +b2NhbGhvc3QwHhcNMTQwOTEwMjE0MzA1WhcNMTQxMDEwMjE0MzA1WjAUMRIwEAYD +VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDR +0KfxUw7MF/8RB5/YXOM7yLnoHYb/M/6dyoulMbtEdKKhQhU28o5FiDkHcEG9PJQL +gqrRgAjl3VmCC9omtfZJQ2EpfkTttkJjnKOOroXhYE51/CYSckapBYCVh8GkjUEJ +uEfnp07cTfYZFqViIgIWPZyjkzl3w4girS7kCuzNdDntVJVx5F/EsFwMA8n3C0Qa +zHQoM5s00Fer6aTwd6AW0JD5QkADavpfzZ554e4HrVGwHlM28WKQQkFzzGu44FFX +yVuEF3HeyVPug8GRHAc8UU7ijVgJB5TmbvRGYowIErD5i4VvGLuOv9mgR3aVyN0S +dJ1N7aJnXpeSQjAgf03jAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAE4yvwhbPldg +Bpl7sBw/m2B3bfiNeSqa4tII1PQ7ysgWVb9HbFNKkriScwDWlqo6ljZfJ+SDFCoj +bQz4fOFdMAOzRnpTrG2NAKMoJLY0/g/p7XO00PiC8T3h3BOJ5SHuW3gUyfGXmAYs +DnJxJOrwPzj57xvNXjNSbDOJ3DRfCbB0CWBexOeGDiUokoEq3Gnz04Q4ZfHyAcpZ +3deMw8Od5p9WAoCh3oClpFyOSzXYKZd+3ppMMtfc4wnbfocnfSFxj0UCpOEJw4Ez ++lGuHKdhNOVW9CmqPD1y76o6c8PQKuF7KZEoY2jvy3GeIfddBvqXgZ4PbWvFz1jO +32C9XWHwRA4= +-----END CERTIFICATE----- diff --git a/spring-boot-project/spring-boot/src/test/resources/test-key.pem b/spring-boot-project/spring-boot/src/test/resources/test-key.pem new file mode 100644 index 000000000000..00d439edc6b0 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/test-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDR0KfxUw7MF/8R +B5/YXOM7yLnoHYb/M/6dyoulMbtEdKKhQhU28o5FiDkHcEG9PJQLgqrRgAjl3VmC +C9omtfZJQ2EpfkTttkJjnKOOroXhYE51/CYSckapBYCVh8GkjUEJuEfnp07cTfYZ +FqViIgIWPZyjkzl3w4girS7kCuzNdDntVJVx5F/EsFwMA8n3C0QazHQoM5s00Fer +6aTwd6AW0JD5QkADavpfzZ554e4HrVGwHlM28WKQQkFzzGu44FFXyVuEF3HeyVPu +g8GRHAc8UU7ijVgJB5TmbvRGYowIErD5i4VvGLuOv9mgR3aVyN0SdJ1N7aJnXpeS +QjAgf03jAgMBAAECggEBAIhQyzwj3WJGWOZkkLqOpufJotcmj/Wwf0VfOdkq9WMl +cB/bAlN/xWVxerPVgDCFch4EWBzi1WUaqbOvJZ2u7QNubmr56aiTmJCFTVI/GyZx +XqiTGN01N6lKtN7xo6LYTyAUhUsBTWAemrx0FSErvTVb9C/mUBj6hbEZ2XQ5kN5t +7qYX4Lu0zyn7s1kX5SLtm5I+YRq7HSwB6wLy+DSroO71izZ/VPwME3SwT5SN+c87 +3dkklR7fumNd9dOpSWKrLPnq4aMko00rvIGc63xD1HrEpXUkB5v24YEn7HwCLEH7 +b8jrp79j2nCvvR47inpf+BR8FIWAHEOUUqCEzjQkdiECgYEA6ifjMM0f02KPeIs7 +zXd1lI7CUmJmzkcklCIpEbKWf/t/PHv3QgqIkJzERzRaJ8b+GhQ4zrSwAhrGUmI8 +kDkXIqe2/2ONgIOX2UOHYHyTDQZHnlXyDecvHUTqs2JQZCGBZkXyZ9i0j3BnTymC +iZ8DvEa0nxsbP+U3rgzPQmXiQVMCgYEA5WN2Y/RndbriNsNrsHYRldbPO5nfV9rp +cDzcQU66HRdK5VIdbXT9tlMYCJIZsSqE0tkOwTgEB/sFvF/tIHSCY5iO6hpIyk6g +kkUzPcld4eM0dEPAge7SYUbakB9CMvA7MkDQSXQNFyZ0mH83+UikwT6uYHFh7+ox +N1P+psDhXzECgYEA1gXLVQnIcy/9LxMkgDMWV8j8uMyUZysDthpbK3/uq+A2dhRg +9g4msPd5OBQT65OpIjElk1n4HpRWfWqpLLHiAZ0GWPynk7W0D7P3gyuaRSdeQs0P +x8FtgPVDCN9t13gAjHiWjnC26Py2kNbCKAQeJ/MAmQTvrUFX2VCACJKTcV0CgYAj +xJWSUmrLfb+GQISLOG3Xim434e9keJsLyEGj4U29+YLRLTOvfJ2PD3fg5j8hU/rw +Ea5uTHi8cdTcIa0M8X3fX8txD3YoLYh2JlouGTcNYOst8d6TpBSj3HN6I5Wj8beZ +R2fy/CiKYpGtsbCdq0kdZNO18BgQW9kewncjs1GxEQKBgQCf8q34h6KuHpHSDh9h +YkDTypk0FReWBAVJCzDNDUMhVLFivjcwtaMd2LiC3FMKZYodr52iKg60cj43vbYI +frmFFxoL37rTmUocCTBKc0LhWj6MicI+rcvQYe1uwTrpWdFf1aZJMYRLRczeKtev +OWaE/9hVZ5+9pild1NukGpOydw== +-----END PRIVATE KEY----- diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CustomServletPathSampleActuatorTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CustomServletPathSampleActuatorTests.java index 21c55cf772af..9bccb2246a5b 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CustomServletPathSampleActuatorTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CustomServletPathSampleActuatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-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. @@ -18,7 +18,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.core.env.Environment; /** diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortAndPathSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortAndPathSampleActuatorApplicationTests.java index 7365b5a5b129..9c24a3270848 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortAndPathSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortAndPathSampleActuatorApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-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. @@ -19,11 +19,11 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortCustomServletPathSampleActuatorTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortCustomServletPathSampleActuatorTests.java index d8fb11a4eed1..ce2fb6f68b80 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortCustomServletPathSampleActuatorTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortCustomServletPathSampleActuatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -19,10 +19,10 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/SampleActuatorCustomSecurityApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/SampleActuatorCustomSecurityApplicationTests.java index 841e9c964636..221c7daab86a 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/SampleActuatorCustomSecurityApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/SampleActuatorCustomSecurityApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -22,7 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-ui/src/test/java/smoketest/actuator/ui/SampleActuatorUiApplicationPortTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-ui/src/test/java/smoketest/actuator/ui/SampleActuatorUiApplicationPortTests.java index c8009a6a5c06..878c403c4cb9 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-ui/src/test/java/smoketest/actuator/ui/SampleActuatorUiApplicationPortTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-ui/src/test/java/smoketest/actuator/ui/SampleActuatorUiApplicationPortTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -20,11 +20,11 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/AbstractManagementPortAndPathSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/AbstractManagementPortAndPathSampleActuatorApplicationTests.java index ac9e1b5bb0ec..79bd73ce278c 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/AbstractManagementPortAndPathSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/AbstractManagementPortAndPathSampleActuatorApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -21,9 +21,9 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementAddressActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementAddressActuatorApplicationTests.java index 298ea9f80d0b..6e9a137baa7c 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementAddressActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementAddressActuatorApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-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. @@ -20,11 +20,11 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java index d4885013374e..9e3b73ac5106 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -18,9 +18,9 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalManagementPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortSampleActuatorApplicationTests.java index f69f1001c9ca..20a86d394af0 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortSampleActuatorApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -22,12 +22,12 @@ import smoketest.actuator.ManagementPortSampleActuatorApplicationTests.CustomErrorAttributes; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortWithLazyInitializationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortWithLazyInitializationTests.java index 518f05fad711..301befa38164 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortWithLazyInitializationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortWithLazyInitializationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -18,9 +18,9 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalManagementPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-client/src/test/java/smoketest/oauth2/client/SampleOAuth2ClientApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-client/src/test/java/smoketest/oauth2/client/SampleOAuth2ClientApplicationTests.java index 6ce6e5efb06f..e8ab5308e939 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-client/src/test/java/smoketest/oauth2/client/SampleOAuth2ClientApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-client/src/test/java/smoketest/oauth2/client/SampleOAuth2ClientApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -23,7 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-profile/src/test/java/smoketest/profile/ActiveProfilesTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-profile/src/test/java/smoketest/profile/ActiveProfilesTests.java index 51a66ee2bd00..e116c52bbedd 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-profile/src/test/java/smoketest/profile/ActiveProfilesTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-profile/src/test/java/smoketest/profile/ActiveProfilesTests.java @@ -33,8 +33,7 @@ * * @author Madhura Bhave */ -@SpringBootTest(webEnvironment = WebEnvironment.NONE, - properties = { "enableEnvironmentPostProcessor=true", "server.port=0" }) // gh-28530 +@SpringBootTest(webEnvironment = WebEnvironment.NONE, properties = { "enableEnvironmentPostProcessor=true" }) // gh-28530 @ActiveProfiles("hello") class ActiveProfilesTests { diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-rsocket/src/test/java/smoketest/rsocket/SampleRSocketApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-rsocket/src/test/java/smoketest/rsocket/SampleRSocketApplicationTests.java index a3bab71de4bc..97a5899cbd18 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-rsocket/src/test/java/smoketest/rsocket/SampleRSocketApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-rsocket/src/test/java/smoketest/rsocket/SampleRSocketApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -23,8 +23,8 @@ import reactor.test.StepVerifier; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.rsocket.context.LocalRSocketServerPort; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.rsocket.server.LocalRSocketServerPort; import org.springframework.messaging.rsocket.RSocketRequester; import org.springframework.security.rsocket.metadata.SimpleAuthenticationEncoder; import org.springframework.security.rsocket.metadata.UsernamePasswordMetadata; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/main/resources/application.yml b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/main/resources/application.yml index 4256d2d331c1..83ac8e90b398 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/main/resources/application.yml +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/main/resources/application.yml @@ -8,10 +8,10 @@ spring: credentials: - private-key-location: "classpath:saml/privatekey.txt" certificate-location: "classpath:saml/certificate.txt" - identityprovider: + asserting-party: verification: credentials: - - certificate-location: "classpath:saml/certificate.txt" + - certificate-location: "classpath:saml/certificate.txt" entity-id: simplesaml singlesignon: url: https://simplesaml-for-spring-saml/SSOService.php @@ -21,10 +21,10 @@ spring: credentials: - private-key-location: "classpath:saml/privatekey.txt" certificate-location: "classpath:saml/certificate.txt" - identityprovider: + asserting-party: verification: credentials: - - certificate-location: "classpath:saml/certificate.txt" + - certificate-location: "classpath:saml/certificate.txt" entity-id: okta-id-1234 singlesignon: url: diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/test/java/smoketest/saml2/serviceprovider/SampleSaml2RelyingPartyApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/test/java/smoketest/saml2/serviceprovider/SampleSaml2RelyingPartyApplicationTests.java index b38cd2896b65..7250bc1afc48 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/test/java/smoketest/saml2/serviceprovider/SampleSaml2RelyingPartyApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/test/java/smoketest/saml2/serviceprovider/SampleSaml2RelyingPartyApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -23,7 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -46,7 +46,7 @@ void everythingShouldRedirectToLogin() { } @Test - void loginShouldHaveAllIdentityProvidersToChooseFrom() { + void loginShouldHaveAllAssertingPartiesToChooseFrom() { ResponseEntity entity = this.restTemplate.getForEntity("/login", String.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(entity.getBody()).contains("/saml2/authenticate/simplesamlphp"); diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/ManagementPortSampleSecureWebFluxTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/ManagementPortSampleSecureWebFluxTests.java index e338be7593ac..a0cebf047dc6 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/ManagementPortSampleSecureWebFluxTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/ManagementPortSampleSecureWebFluxTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -22,12 +22,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.autoconfigure.security.reactive.EndpointRequest; -import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.actuate.web.mappings.MappingsEndpoint; import org.springframework.boot.autoconfigure.security.reactive.PathRequest; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.web.server.ServerHttpSecurity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/test/java/smoketest/session/redis/SampleSessionRedisApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/test/java/smoketest/session/redis/SampleSessionRedisApplicationTests.java index 8863197968bf..eca768c384ee 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/test/java/smoketest/session/redis/SampleSessionRedisApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/test/java/smoketest/session/redis/SampleSessionRedisApplicationTests.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Map; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -60,6 +61,7 @@ static void applicationProperties(DynamicPropertyRegistry registry) { } @Test + @Disabled("See gh-30673") @SuppressWarnings("unchecked") void sessionsEndpointShouldReturnUserSessions() { createSession(URI.create("/")); diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux/src/test/java/smoketest/session/SampleSessionWebFluxApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux/src/test/java/smoketest/session/SampleSessionWebFluxApplicationTests.java index d7238c9fc607..f19abfcfba14 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux/src/test/java/smoketest/session/SampleSessionWebFluxApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux/src/test/java/smoketest/session/SampleSessionWebFluxApplicationTests.java @@ -25,8 +25,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.testsupport.junit.DisabledOnOs; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.web.reactive.function.client.WebClient; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-multi-connectors/src/test/java/smoketest/tomcat/multiconnector/SampleTomcatTwoConnectorsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-multi-connectors/src/test/java/smoketest/tomcat/multiconnector/SampleTomcatTwoConnectorsApplicationTests.java index 83ecd7e19993..590bddf8238a 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-multi-connectors/src/test/java/smoketest/tomcat/multiconnector/SampleTomcatTwoConnectorsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-multi-connectors/src/test/java/smoketest/tomcat/multiconnector/SampleTomcatTwoConnectorsApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -26,10 +26,10 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.context.WebServerInitializedEvent; import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/build.gradle new file mode 100644 index 000000000000..077f6cd415ee --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/build.gradle @@ -0,0 +1,13 @@ +plugins { + id "java" + id "org.springframework.boot.conventions" +} + +description = "Spring Boot web application type smoke test" + +dependencies { + implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) + implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-webflux")) + + testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/main/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplication.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/main/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplication.java new file mode 100644 index 000000000000..6d836ae1bd92 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/main/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplication.java @@ -0,0 +1,29 @@ +/* + * Copyright 2012-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 smoketest.webapplicationtype; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SampleWebApplicationTypeApplication { + + public static void main(String[] args) { + SpringApplication.run(SampleWebApplicationTypeApplication.class, args); + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/main/resources/application.properties b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/main/resources/application.properties new file mode 100644 index 000000000000..a8cc36cc0a56 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.main.web-application-type=reactive diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/OverriddenWebApplicationTypeApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/OverriddenWebApplicationTypeApplicationTests.java new file mode 100644 index 000000000000..217f7faeb9ec --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/OverriddenWebApplicationTypeApplicationTests.java @@ -0,0 +1,44 @@ +/* + * Copyright 2012-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 smoketest.webapplicationtype; + +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationContext; +import org.springframework.web.context.WebApplicationContext; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for an application using an overridden web application type + * + * @author Andy Wilkinson + */ +@SpringBootTest(properties = "spring.main.web-application-type=servlet") +class OverriddenWebApplicationTypeApplicationTests { + + @Autowired + private ApplicationContext context; + + @Test + void contextIsServlet() { + assertThat(this.context).isInstanceOf(WebApplicationContext.class); + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplicationTests.java new file mode 100644 index 000000000000..a3fabb10ef1e --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplicationTests.java @@ -0,0 +1,44 @@ +/* + * Copyright 2012-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 smoketest.webapplicationtype; + +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; +import org.springframework.context.ApplicationContext; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for an application using a configured web application type + * + * @author Andy Wilkinson + */ +@SpringBootTest +class SampleWebApplicationTypeApplicationTests { + + @Autowired + private ApplicationContext context; + + @Test + void contextIsReactive() { + assertThat(this.context).isInstanceOf(ReactiveWebApplicationContext.class); + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/WebEnvironmentNoneOverridesWebApplicationTypeTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/WebEnvironmentNoneOverridesWebApplicationTypeTests.java new file mode 100644 index 000000000000..c3275a9944a3 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/WebEnvironmentNoneOverridesWebApplicationTypeTests.java @@ -0,0 +1,48 @@ +/* + * Copyright 2012-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 smoketest.webapplicationtype; + +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; +import org.springframework.context.ApplicationContext; +import org.springframework.web.context.WebApplicationContext; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for a web environment of none overriding the configured web + * application type. + * + * @author Andy Wilkinson + */ +@SpringBootTest(webEnvironment = WebEnvironment.NONE) +class WebEnvironmentNoneOverridesWebApplicationTypeTests { + + @Autowired + private ApplicationContext context; + + @Test + void contextIsPlain() { + assertThat(this.context).isNotInstanceOf(ReactiveWebApplicationContext.class); + assertThat(this.context).isNotInstanceOf(WebApplicationContext.class); + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-groovy-templates/src/test/java/smoketest/groovytemplates/SampleGroovyTemplateApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-groovy-templates/src/test/java/smoketest/groovytemplates/SampleGroovyTemplateApplicationTests.java index be72ca9e134b..a52c86691ae3 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-groovy-templates/src/test/java/smoketest/groovytemplates/SampleGroovyTemplateApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-groovy-templates/src/test/java/smoketest/groovytemplates/SampleGroovyTemplateApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -24,7 +24,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.util.LinkedMultiValueMap; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/test/java/smoketest/security/method/SampleMethodSecurityApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/test/java/smoketest/security/method/SampleMethodSecurityApplicationTests.java index 79147ca0ab18..c84ea18c9344 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/test/java/smoketest/security/method/SampleMethodSecurityApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/test/java/smoketest/security/method/SampleMethodSecurityApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -24,7 +24,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-custom/src/test/java/smoketest/web/secure/custom/SampleWebSecureCustomApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-custom/src/test/java/smoketest/web/secure/custom/SampleWebSecureCustomApplicationTests.java index 6fabfa8e7bc5..5580a3ce55e7 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-custom/src/test/java/smoketest/web/secure/custom/SampleWebSecureCustomApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-custom/src/test/java/smoketest/web/secure/custom/SampleWebSecureCustomApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -24,7 +24,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-jdbc/src/test/java/smoketest/web/secure/jdbc/SampleWebSecureJdbcApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-jdbc/src/test/java/smoketest/web/secure/jdbc/SampleWebSecureJdbcApplicationTests.java index 19e2e17ebd7e..ee35c052e9b2 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-jdbc/src/test/java/smoketest/web/secure/jdbc/SampleWebSecureJdbcApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-jdbc/src/test/java/smoketest/web/secure/jdbc/SampleWebSecureJdbcApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -24,7 +24,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/SampleWebSecureApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/SampleWebSecureApplicationTests.java index d6c36befff13..6794d3e40390 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/SampleWebSecureApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/SampleWebSecureApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-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. @@ -24,7 +24,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-thymeleaf/src/test/java/smoketest/web/thymeleaf/SampleWebUiApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-thymeleaf/src/test/java/smoketest/web/thymeleaf/SampleWebUiApplicationTests.java index b9509e4371b7..d658586cb12b 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-thymeleaf/src/test/java/smoketest/web/thymeleaf/SampleWebUiApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-thymeleaf/src/test/java/smoketest/web/thymeleaf/SampleWebUiApplicationTests.java @@ -24,7 +24,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.util.LinkedMultiValueMap; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java index d0450b917070..d22383653c2f 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -18,9 +18,9 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalManagementPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webservices/src/test/java/smoketest/webservices/SampleWsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webservices/src/test/java/smoketest/webservices/SampleWsApplicationTests.java index 8f982e5e8251..ae53d8cb3207 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webservices/src/test/java/smoketest/webservices/SampleWsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webservices/src/test/java/smoketest/webservices/SampleWsApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -29,7 +29,7 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.ws.client.core.WebServiceTemplate; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/SampleWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/SampleWebSocketsApplicationTests.java index d8fb35d08fd6..e66096c99a71 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/SampleWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/SampleWebSocketsApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -33,7 +33,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/echo/CustomContainerWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/echo/CustomContainerWebSocketsApplicationTests.java index ddafe23c9a55..ccfb5ff35b8e 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/echo/CustomContainerWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/echo/CustomContainerWebSocketsApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -35,8 +35,8 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/SampleWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/SampleWebSocketsApplicationTests.java index c76d16b7ef42..642e60b98394 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/SampleWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/SampleWebSocketsApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -33,7 +33,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/echo/CustomContainerWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/echo/CustomContainerWebSocketsApplicationTests.java index bc935fb5c977..5f2611993153 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/echo/CustomContainerWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/echo/CustomContainerWebSocketsApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -35,8 +35,8 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/SampleWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/SampleWebSocketsApplicationTests.java index a2648eb93308..0ab9771969b1 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/SampleWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/SampleWebSocketsApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -33,7 +33,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/echo/CustomContainerWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/echo/CustomContainerWebSocketsApplicationTests.java index 471b8551f23b..f0a361fa0587 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/echo/CustomContainerWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/echo/CustomContainerWebSocketsApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-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. @@ -35,8 +35,8 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; diff --git a/src/checkstyle/import-control.xml b/src/checkstyle/import-control.xml index 397dc03fb6ae..089b4371a989 100644 --- a/src/checkstyle/import-control.xml +++ b/src/checkstyle/import-control.xml @@ -93,6 +93,9 @@ + + + From 4da3c69a10ce66c13b4cf280d0a678cfd962a50a Mon Sep 17 00:00:00 2001 From: Almog Tavor Date: Wed, 20 Apr 2022 18:17:51 +0300 Subject: [PATCH 09/12] Fix: formatting and checkstyle notes --- .../kafka/ReactiveKafkaAutoConfiguration.java | 66 +++++++++++-------- .../kafka/ReactiveKafkaProperties.java | 30 +++------ .../ReactiveKafkaAutoConfigurationTests.java | 52 +++++++-------- 3 files changed, 74 insertions(+), 74 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java index 8fd6bf025b74..3a00a97a3d7f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfiguration.java @@ -16,6 +16,15 @@ package org.springframework.boot.autoconfigure.kafka; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; + +import reactor.kafka.receiver.KafkaReceiver; +import reactor.kafka.receiver.ReceiverOptions; +import reactor.kafka.sender.KafkaSender; +import reactor.kafka.sender.SenderOptions; + import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -24,14 +33,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.context.annotation.Bean; -import reactor.kafka.receiver.KafkaReceiver; -import reactor.kafka.receiver.ReceiverOptions; -import reactor.kafka.sender.KafkaSender; -import reactor.kafka.sender.SenderOptions; - -import java.util.Map; -import java.util.Optional; -import java.util.function.Function; /** * {@link EnableAutoConfiguration Auto-configuration} for the Reactive client of Apache @@ -41,15 +42,19 @@ * @since 2.7.0 */ @AutoConfiguration -@ConditionalOnClass({KafkaReceiver.class, KafkaSender.class}) +@ConditionalOnClass({ KafkaReceiver.class, KafkaSender.class }) @ConditionalOnBean(KafkaProperties.class) @EnableConfigurationProperties(ReactiveKafkaProperties.class) public class ReactiveKafkaAutoConfiguration { + private final KafkaProperties kafkaProperties; + private final ReactiveKafkaProperties reactiveKafkaProperties; + private static final PropertyMapper map = PropertyMapper.get(); - public ReactiveKafkaAutoConfiguration(KafkaProperties kafkaProperties, ReactiveKafkaProperties reactiveKafkaProperties) { + public ReactiveKafkaAutoConfiguration(KafkaProperties kafkaProperties, + ReactiveKafkaProperties reactiveKafkaProperties) { this.kafkaProperties = kafkaProperties; this.reactiveKafkaProperties = reactiveKafkaProperties; } @@ -60,16 +65,25 @@ public ReceiverOptions receiverOptions() { Map properties = this.kafkaProperties.buildConsumerProperties(); ReceiverOptions receiverOptions = ReceiverOptions.create(properties); ReactiveKafkaProperties.Receiver receiverProperties = this.reactiveKafkaProperties.getReceiver(); - receiverOptions = setPropertyWhenGreaterThanZero(receiverProperties.getAtmostOnceCommitAheadSize(), receiverOptions::atmostOnceCommitAheadSize, receiverOptions); - receiverOptions = setPropertyWhenGreaterThanZero(receiverProperties.getMaxDeferredCommits(), receiverOptions::maxDeferredCommits, receiverOptions); - receiverOptions = setPropertyWhenGreaterThanZero(receiverProperties.getMaxCommitAttempts(), receiverOptions::maxCommitAttempts, receiverOptions); - receiverOptions = setPropertyWhenGreaterThanZero(receiverProperties.getCommitBatchSize(), receiverOptions::commitBatchSize, receiverOptions); - receiverOptions = setPropertyWhenNonNull(receiverProperties.getCloseTimeout(), receiverOptions::closeTimeout, receiverOptions); - receiverOptions = setPropertyWhenNonNull(receiverProperties.getPollTimeout(), receiverOptions::pollTimeout, receiverOptions); - receiverOptions = setPropertyWhenNonNull(receiverProperties.getCommitInterval(), receiverOptions::commitInterval, receiverOptions); - receiverOptions = setPropertyWhenNonNull(receiverProperties.getSubscribeTopics(), receiverOptions::subscription, receiverOptions); + receiverOptions = setPropertyWhenGreaterThanZero(receiverProperties.getAtmostOnceCommitAheadSize(), + receiverOptions::atmostOnceCommitAheadSize, receiverOptions); + receiverOptions = setPropertyWhenGreaterThanZero(receiverProperties.getMaxDeferredCommits(), + receiverOptions::maxDeferredCommits, receiverOptions); + receiverOptions = setPropertyWhenGreaterThanZero(receiverProperties.getMaxCommitAttempts(), + receiverOptions::maxCommitAttempts, receiverOptions); + receiverOptions = setPropertyWhenGreaterThanZero(receiverProperties.getCommitBatchSize(), + receiverOptions::commitBatchSize, receiverOptions); + receiverOptions = setPropertyWhenNonNull(receiverProperties.getCloseTimeout(), receiverOptions::closeTimeout, + receiverOptions); + receiverOptions = setPropertyWhenNonNull(receiverProperties.getPollTimeout(), receiverOptions::pollTimeout, + receiverOptions); + receiverOptions = setPropertyWhenNonNull(receiverProperties.getCommitInterval(), + receiverOptions::commitInterval, receiverOptions); + receiverOptions = setPropertyWhenNonNull(receiverProperties.getSubscribeTopics(), receiverOptions::subscription, + receiverOptions); if (Optional.ofNullable(receiverProperties.getSubscribeTopics()).isEmpty()) { - receiverOptions = setPropertyWhenNonNull(receiverProperties.getSubscribePattern(), receiverOptions::subscription, receiverOptions); + receiverOptions = setPropertyWhenNonNull(receiverProperties.getSubscribePattern(), + receiverOptions::subscription, receiverOptions); } return receiverOptions; } @@ -77,11 +91,12 @@ public ReceiverOptions receiverOptions() { @Bean @ConditionalOnMissingBean(SenderOptions.class) public SenderOptions senderOptions() { - Map properties = kafkaProperties.buildProducerProperties(); + Map properties = this.kafkaProperties.buildProducerProperties(); SenderOptions senderOptions = SenderOptions.create(properties); ReactiveKafkaProperties.Sender senderProperties = this.reactiveKafkaProperties.getSender(); senderOptions = map.from(senderProperties.getCloseTimeout()).toInstance(senderOptions::closeTimeout); - senderOptions = setPropertyWhenGreaterThanZero(senderProperties.getMaxInFlight(), senderOptions::maxInFlight, senderOptions); + senderOptions = setPropertyWhenGreaterThanZero(senderProperties.getMaxInFlight(), senderOptions::maxInFlight, + senderOptions); senderOptions = map.from(senderProperties.isStopOnError()).toInstance(senderOptions::stopOnError); return senderOptions; } @@ -90,17 +105,14 @@ private T setPropertyWhenGreaterThanZero(Integer property, Function i > 0) - .toInstance(function); + return map.from(property).when((i) -> i > 0).toInstance(function); } private T setPropertyWhenNonNull(S property, Function function, T options) { if (Optional.ofNullable(property).isEmpty()) { return options; } - return map.from(property) - .whenNonNull() - .toInstance(function); + return map.from(property).whenNonNull().toInstance(function); } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java index 67b08e4e319b..58d80edac324 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java @@ -16,18 +16,19 @@ package org.springframework.boot.autoconfigure.kafka; -import org.apache.kafka.clients.consumer.KafkaConsumer; -import org.apache.kafka.clients.consumer.RetriableCommitFailedException; -import org.apache.kafka.clients.producer.ProducerConfig; -import org.springframework.boot.context.properties.ConfigurationProperties; -import reactor.kafka.receiver.KafkaReceiver; - import java.time.Duration; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.regex.Pattern; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.consumer.RetriableCommitFailedException; +import org.apache.kafka.clients.producer.ProducerConfig; +import reactor.kafka.receiver.KafkaReceiver; + +import org.springframework.boot.context.properties.ConfigurationProperties; + /** * Configuration properties for Project Reactor for Apache Kafka. *

@@ -196,6 +197,7 @@ public int getMaxDeferredCommits() { public void setMaxDeferredCommits(int maxDeferredCommits) { this.maxDeferredCommits = maxDeferredCommits; } + } public static class Sender { @@ -255,21 +257,7 @@ public void setCloseTimeout(Duration closeTimeout) { public Map getProperties() { return this.properties; } - } - - @SuppressWarnings("serial") - public static class Properties extends HashMap { - - public java.util.function.Consumer in(String key) { - return (value) -> put(key, value); - } - public Properties with(KafkaProperties.Ssl ssl, KafkaProperties.Security security, - Map properties) { - putAll(ssl.buildProperties()); - putAll(security.buildProperties()); - putAll(properties); - return this; - } } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java index c56cc940b48d..b77bb3d470dc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaAutoConfigurationTests.java @@ -16,17 +16,18 @@ package org.springframework.boot.autoconfigure.kafka; -import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import reactor.kafka.receiver.ReceiverOptions; -import reactor.kafka.sender.SenderOptions; - import java.time.Duration; import java.util.Arrays; import java.util.Objects; import java.util.regex.Pattern; +import org.junit.jupiter.api.Test; +import reactor.kafka.receiver.ReceiverOptions; +import reactor.kafka.sender.SenderOptions; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + import static org.assertj.core.api.Assertions.assertThat; /** @@ -35,6 +36,7 @@ * @author Almog Tavor */ class ReactiveKafkaAutoConfigurationTests { + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(KafkaAutoConfiguration.class)) .withConfiguration(AutoConfigurations.of(ReactiveKafkaAutoConfiguration.class)); @@ -49,16 +51,16 @@ void receiverProperties() { "spring.reactor.kafka.receiver.max-commit-attempts=3", "spring.reactor.kafka.receiver.max-deferred-commits=5", "spring.reactor.kafka.receiver.subscribe-topics=foo,bar").run((context) -> { - ReceiverOptions receiverOptions = context.getBean(ReceiverOptions.class); - assertThat(receiverOptions.commitInterval()).isEqualTo(Duration.ofSeconds(2)); - assertThat(receiverOptions.closeTimeout()).isEqualTo(Duration.ofMillis(1500)); - assertThat(receiverOptions.commitBatchSize()).isEqualTo(100); - assertThat(receiverOptions.pollTimeout()).isEqualTo(Duration.ofSeconds(1)); - assertThat(receiverOptions.atmostOnceCommitAheadSize()).isEqualTo(42); - assertThat(receiverOptions.maxCommitAttempts()).isEqualTo(3); - assertThat(receiverOptions.maxDeferredCommits()).isEqualTo(5); - assertThat(receiverOptions.subscriptionTopics()).containsAll(Arrays.asList("foo", "bar")); - }); + ReceiverOptions receiverOptions = context.getBean(ReceiverOptions.class); + assertThat(receiverOptions.commitInterval()).isEqualTo(Duration.ofSeconds(2)); + assertThat(receiverOptions.closeTimeout()).isEqualTo(Duration.ofMillis(1500)); + assertThat(receiverOptions.commitBatchSize()).isEqualTo(100); + assertThat(receiverOptions.pollTimeout()).isEqualTo(Duration.ofSeconds(1)); + assertThat(receiverOptions.atmostOnceCommitAheadSize()).isEqualTo(42); + assertThat(receiverOptions.maxCommitAttempts()).isEqualTo(3); + assertThat(receiverOptions.maxDeferredCommits()).isEqualTo(5); + assertThat(receiverOptions.subscriptionTopics()).containsAll(Arrays.asList("foo", "bar")); + }); } @Test @@ -73,24 +75,22 @@ void receiverPropertiesSubscribePattern() { @Test void receiverPropertiesDefaultValues() { - this.contextRunner.withPropertyValues() - .run((context) -> { - ReceiverOptions receiverOptions = context.getBean(ReceiverOptions.class); - assertThat(receiverOptions.commitInterval()).isEqualTo(Duration.ofSeconds(5)); - }); + this.contextRunner.withPropertyValues().run((context) -> { + ReceiverOptions receiverOptions = context.getBean(ReceiverOptions.class); + assertThat(receiverOptions.commitInterval()).isEqualTo(Duration.ofSeconds(5)); + }); } @Test void producerProperties() { - this.contextRunner.withPropertyValues( - "spring.reactor.kafka.sender.max-in-flight=1500", "spring.reactor.kafka.sender.stop-on-error=false", - "spring.reactor.kafka.sender.close-timeout=500") + this.contextRunner.withPropertyValues("spring.reactor.kafka.sender.max-in-flight=1500", + "spring.reactor.kafka.sender.stop-on-error=false", "spring.reactor.kafka.sender.close-timeout=500") .run((context) -> { - SenderOptions senderOptions = context - .getBean(SenderOptions.class); + SenderOptions senderOptions = context.getBean(SenderOptions.class); assertThat(senderOptions.maxInFlight()).isEqualTo(1500); assertThat(senderOptions.stopOnError()).isFalse(); assertThat(senderOptions.closeTimeout()).isEqualTo(Duration.ofMillis(500)); }); } + } From c644529e8b9da61c1a1400b2188424522b7d3082 Mon Sep 17 00:00:00 2001 From: Almog Tavor Date: Wed, 20 Apr 2022 18:24:04 +0300 Subject: [PATCH 10/12] Fix: simplify javadoc notes --- .../kafka/ReactiveKafkaProperties.java | 36 +++++-------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java index 58d80edac324..6ebeaa8f28d0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java @@ -66,16 +66,12 @@ public Sender getSender() { public static class Receiver { /** - * Sets the timeout for each {@link KafkaConsumer#poll(Duration)} operation. Since - * the underlying Kafka consumer is not thread-safe, long poll intervals may delay - * commits and other operations invoked using - * {@link KafkaReceiver#doOnConsumer(java.util.function.Function)}. Very short - * timeouts may reduce batching and increase load on the broker. + * Sets the timeout for each KafkaConsumer's poll operation duration. */ private Duration pollTimeout; /** - * Sets timeout for graceful shutdown of {@link KafkaConsumer}. + * Sets timeout for graceful shutdown of the KafkaConsumer. */ private Duration closeTimeout; @@ -104,24 +100,18 @@ public static class Receiver { /** * Configures commit ahead size per partition for at-most-once delivery. Before - * dispatching each record, an offset ahead by this size may be committed. The - * maximum number of records that may be lost if the application fails is - * commitAheadSize + 1. + * dispatching each record, an offset ahead by this size may be committed. */ private int atmostOnceCommitAheadSize; /** - * Configures the maximum number of consecutive non-fatal - * {@link RetriableCommitFailedException} commit failures that are tolerated. For - * manual commits, failure in commit after the configured number of attempts fails - * the commit operation. For auto commits, the received Flux is terminated if the - * commit does not succeed after these attempts. + * Configures the maximum number of consecutive non-fatal RetriableCommitFailedException + * commit failures that are tolerated. */ private int maxCommitAttempts; /** - * Set to greater than 0 to enable out of order commit sequencing. If the number - * of deferred commits exceeds this value, the consumer is paused until the + * The limit for the number of deferred commits to pause the consumer until the * deferred commits are reduced. */ private int maxDeferredCommits; @@ -206,22 +196,12 @@ public static class Sender { /** * Configures the maximum number of in-flight records that are fetched from the - * outbound record publisher while acknowledgements are pending. This limit must - * be configured along with {@link ProducerConfig#BUFFER_MEMORY_CONFIG} to control - * memory usage and to avoid blocking the reactive pipeline. + * outbound record publisher while acknowledgements are pending. */ private int maxInFlight; /** - * Configures error handling behaviour for - * {@link reactor.kafka.sender.KafkaSender#send(org.reactivestreams.Publisher)}. - * If set to true, send fails when an error is encountered and only records that - * are already in transit may be delivered after the first error. If set to false, - * an attempt is made to send each record to Kafka, even if one or more records - * cannot be delivered after the configured number of retries due to a non-fatal - * exception. This flag should be set along with - * {@link ProducerConfig#RETRIES_CONFIG} and {@link ProducerConfig#ACKS_CONFIG} to - * configure the required quality-of-service. By default, stopOnError is true. + * Configures error handling behaviour for the KafkaSender's send function. */ private boolean stopOnError; From 37059a5e92c170766d5c89f75870056c69328e38 Mon Sep 17 00:00:00 2001 From: Almog Tavor Date: Wed, 20 Apr 2022 18:26:57 +0300 Subject: [PATCH 11/12] Revert "Merge branch 'spring-projects:main' into main" This reverts commit ce390b00e1e314d07caff984db054741c71ce29c. --- .../DocumentDevtoolsPropertyDefaults.java | 2 +- ci/images/ci-image-jdk18/Dockerfile | 2 +- ci/images/ci-image/Dockerfile | 2 +- gradle.properties | 2 +- settings.gradle | 2 +- .../build.gradle | 6 +- .../ReactiveCloudFoundrySecurityService.java | 5 +- ...estHealthContributorAutoConfiguration.java | 16 +- .../metrics/JvmMetricsAutoConfiguration.java | 10 +- .../KafkaMetricsAutoConfiguration.java | 4 +- .../Log4J2MetricsAutoConfiguration.java | 2 +- .../LogbackMetricsAutoConfiguration.java | 2 +- .../SystemMetricsAutoConfiguration.java | 6 +- .../CacheMetricsRegistrarConfiguration.java | 4 +- .../export/dynatrace/DynatraceProperties.java | 14 - .../DynatracePropertiesConfigAdapter.java | 5 - .../properties/PropertiesConfigAdapter.java | 4 +- ...vefrontMetricsExportAutoConfiguration.java | 38 ++- .../export/wavefront/WavefrontProperties.java | 132 ++++++++ .../WavefrontPropertiesConfigAdapter.java | 34 +- ...ataSourcePoolMetricsAutoConfiguration.java | 115 +++---- .../mongo/MongoMetricsAutoConfiguration.java | 12 +- .../TaskExecutorMetricsAutoConfiguration.java | 2 +- .../jetty/JettyMetricsAutoConfiguration.java | 6 +- .../TomcatMetricsAutoConfiguration.java | 2 +- .../ObservationAutoConfiguration.java | 4 +- .../ObservationRegistryConfigurer.java | 10 +- .../ObservationRegistryPostProcessor.java | 6 +- .../tracing/BraveAutoConfiguration.java | 129 -------- .../MicrometerTracingAutoConfiguration.java | 46 --- .../OpenTelemetryAutoConfiguration.java | 39 --- .../tracing/OpenTelemetryConfigurations.java | 151 --------- .../tracing/TracingProperties.java | 56 ---- .../autoconfigure/tracing/package-info.java | 20 -- .../wavefront/MeterRegistrySpanMetrics.java | 73 ----- .../WavefrontTracingAutoConfiguration.java | 136 -------- .../tracing/wavefront/package-info.java | 20 -- .../zipkin/ZipkinAutoConfiguration.java | 57 ---- .../tracing/zipkin/ZipkinConfigurations.java | 109 ------- .../tracing/zipkin/ZipkinProperties.java | 71 ----- .../zipkin/ZipkinRestTemplateSender.java | 170 ---------- .../tracing/zipkin/package-info.java | 20 -- .../wavefront/WavefrontAutoConfiguration.java | 61 ---- .../wavefront/WavefrontProperties.java | 290 ------------------ .../autoconfigure/wavefront/package-info.java | 20 -- .../web/server/LocalManagementPort.java | 6 +- ...itional-spring-configuration-metadata.json | 20 +- ...ot.autoconfigure.AutoConfiguration.imports | 6 - .../SpringApplicationHierarchyTests.java | 22 +- ...althContributorAutoConfigurationTests.java | 110 ------- ...althContributorAutoConfigurationTests.java | 6 +- ...ngsEndpointReactiveDocumentationTests.java | 4 +- ...ingsEndpointServletDocumentationTests.java | 4 +- .../MetricsEndpointDocumentationTests.java | 2 +- ...theusScrapeEndpointDocumentationTests.java | 2 +- ...intsAutoConfigurationIntegrationTests.java | 8 +- .../JvmMetricsAutoConfigurationTests.java | 10 +- ...4jLoggerContextAutoConfigurationTests.java | 2 +- ...4jLoggerContextAutoConfigurationTests.java | 2 +- .../LogbackMetricsAutoConfigurationTests.java | 2 +- ...onfigurationWithLog4j2AndLogbackTests.java | 2 +- .../SystemMetricsAutoConfigurationTests.java | 6 +- .../CacheMetricsAutoConfigurationTests.java | 14 +- ...DynatracePropertiesConfigAdapterTests.java | 10 +- ...ioMetricsExportAutoConfigurationTests.java | 2 +- ...hRegistryPropertiesConfigAdapterTests.java | 4 +- ...ntMetricsExportAutoConfigurationTests.java | 69 ++++- ...WavefrontPropertiesConfigAdapterTests.java | 49 +-- .../wavefront/WavefrontPropertiesTests.java} | 20 +- ...urcePoolMetricsAutoConfigurationTests.java | 31 +- .../MongoMetricsAutoConfigurationTests.java | 12 +- .../metrics/test/MetricsIntegrationTests.java | 4 +- .../TomcatMetricsAutoConfigurationTests.java | 2 +- .../ObservationAutoConfigurationTests.java | 16 +- ...mentWebSecurityAutoConfigurationTests.java | 8 +- .../tracing/BraveAutoConfigurationTests.java | 156 ---------- ...crometerTracingAutoConfigurationTests.java | 88 ------ ...gurationsMicrometerConfigurationTests.java | 111 ------- ...ryConfigurationsSdkConfigurationTests.java | 112 ------- ...onfigurationsTracerConfigurationTests.java | 90 ------ .../MeterRegistrySpanMetricsTests.java | 101 ------ ...avefrontTracingAutoConfigurationTests.java | 192 ------------ .../tracing/zipkin/NoopSender.java | 62 ---- .../zipkin/ZipkinAutoConfigurationTests.java | 71 ----- ...ConfigurationsBraveConfigurationTests.java | 92 ------ ...ationsOpenTelemetryConfigurationTests.java | 104 ------- ...figurationsReporterConfigurationTests.java | 97 ------ ...onfigurationsSenderConfigurationTests.java | 100 ------ .../zipkin/ZipkinRestTemplateSenderTests.java | 122 -------- .../WavefrontAutoConfigurationTests.java | 101 ------ .../wavefront/WavefrontPropertiesTests.java | 54 ---- .../spring-boot-actuator/build.gradle | 1 + .../ElasticsearchReactiveHealthIndicator.java | 12 +- ...lasticsearchRestClientHealthIndicator.java | 85 ----- .../ElasticsearchRestHealthIndicator.java | 56 +++- .../CaffeineCacheMeterBinderProvider.java | 2 +- .../HazelcastCacheMeterBinderProvider.java | 2 +- .../cache/JCacheCacheMeterBinderProvider.java | 2 +- .../startup/StartupTimeMetricsListener.java | 4 +- .../system/DiskSpaceMetricsBinder.java | 2 +- .../web/client/RestTemplateExchangeTags.java | 12 +- .../jetty/JettyConnectionMetricsBinder.java | 2 +- .../JettyServerThreadPoolMetricsBinder.java | 2 +- .../jetty/JettySslHandshakeMetricsBinder.java | 2 +- .../client/WebClientExchangeTags.java | 14 +- .../web/reactive/server/WebFluxTags.java | 20 +- .../web/tomcat/TomcatMetricsBinder.java | 2 +- ...ticsearchReactiveHealthIndicatorTests.java | 13 +- ...lasticsearchRestHealthIndicatorTests.java} | 16 +- .../MetricsEndpointWebIntegrationTests.java | 2 +- ...CaffeineCacheMeterBinderProviderTests.java | 2 +- ...azelcastCacheMeterBinderProviderTests.java | 2 +- .../JCacheCacheMeterBinderProviderTests.java | 2 +- .../StartupTimeMetricsListenerTests.java | 2 +- .../client/RestTemplateExchangeTagsTests.java | 19 +- ...ultWebClientExchangeTagsProviderTests.java | 14 +- .../MetricsWebClientFilterFunctionTests.java | 10 +- .../client/WebClientExchangeTagsTests.java | 23 +- .../web/reactive/server/WebFluxTagsTests.java | 4 +- .../spring-boot-autoconfigure/build.gradle | 1 - .../NoSuchBeanDefinitionFailureAnalyzer.java | 15 +- ...sticsearchRestClientAutoConfiguration.java | 3 - ...ElasticsearchRestClientConfigurations.java | 34 +- .../flyway/FlywayAutoConfiguration.java | 9 + .../saml2/Saml2RelyingPartyProperties.java | 10 +- ...RelyingPartyRegistrationConfiguration.java | 25 +- .../session/RedisSessionConfiguration.java | 6 +- .../AbstractErrorWebExceptionHandler.java | 2 +- ...itional-spring-configuration-metadata.json | 96 +----- ...uchBeanDefinitionFailureAnalyzerTests.java | 15 +- ...ientAutoConfigurationIntegrationTests.java | 28 +- ...earchRestClientAutoConfigurationTests.java | 137 +++------ .../gson/GsonAutoConfigurationTests.java | 5 +- ...2ResourceServerAutoConfigurationTests.java | 15 +- ...ml2RelyingPartyAutoConfigurationTests.java | 38 +-- .../Saml2RelyingPartyPropertiesTests.java | 34 +- ...ymeleafReactiveAutoConfigurationTests.java | 3 +- .../WebClientAutoConfigurationTests.java | 29 ++ .../servlet/WelcomePageIntegrationTests.java | 2 +- .../RemappedErrorViewIntegrationTests.java | 4 +- ...SocketMessagingAutoConfigurationTests.java | 10 +- .../spring-boot-dependencies/build.gradle | 80 ++--- ...DevToolsPropertyDefaultsPostProcessor.java | 3 +- .../client/ClassPathChangeUploader.java | 5 +- .../boot/devtools/restart/Restarter.java | 13 +- .../spring-boot-docs/build.gradle | 1 + .../src/docs/asciidoc/actuator/metrics.adoc | 8 +- .../container-images/dockerfiles.adoc | 4 +- .../src/docs/asciidoc/data/nosql.adoc | 19 +- .../asciidoc/features/spring-application.adoc | 3 - .../src/docs/asciidoc/howto/webserver.adoc | 27 +- .../src/docs/asciidoc/messaging/kafka.adoc | 2 +- .../docs/asciidoc/web/spring-security.adoc | 4 +- .../command/CustomCommandTagsProvider.java | 2 +- .../MyCommandTagsProviderConfiguration.java | 2 +- .../CustomConnectionPoolTagsProvider.java | 2 +- ...nnectionPoolTagsProviderConfiguration.java | 2 +- .../MyDataElasticsearchTests.java | 2 +- .../MyUserDocumentationTests.java | 2 +- .../discoverport/MyWebIntegrationTests.java | 4 +- .../command/CustomCommandTagsProvider.kt | 2 +- .../MyCommandTagsProviderConfiguration.kt | 2 +- .../CustomConnectionPoolTagsProvider.kt | 2 +- ...ConnectionPoolTagsProviderConfiguration.kt | 2 +- .../MyUserDocumentationTests.kt | 4 +- .../discoverport/MyWebIntegrationTests.kt | 2 +- .../spring-boot-starter-actuator/build.gradle | 1 + .../build.gradle | 1 + ...AdvancedConfigurationIntegrationTests.java | 2 +- ...DocsAutoConfigurationIntegrationTests.java | 2 +- .../test/context/SpringBootContextLoader.java | 44 +-- .../boot/test/context/SpringBootTest.java | 4 +- .../SpringBootTestContextBootstrapper.java | 8 +- .../server/LocalRSocketServerPort.java | 42 --- .../test/rsocket/server/package-info.java | 20 -- .../test/web/server/LocalManagementPort.java | 41 --- .../boot/test/web/server/LocalServerPort.java | 42 --- .../boot/test/web/server/package-info.java | 20 -- ...stEmbeddedReactiveWebEnvironmentTests.java | 4 +- ...gBootTestWebServerWebEnvironmentTests.java | 2 +- .../context/SpringBootContextLoaderTests.java | 26 -- .../server/LocalRSocketServerPortTests.java | 55 ---- .../web/server/LocalManagementPortTests.java | 54 ---- .../test/web/server/LocalServerPortTests.java | 55 ---- .../buildpack/platform/build/ApiVersions.java | 14 +- .../platform/build/ApiVersionsTests.java | 8 - .../platform/build/LifecycleTests.java | 9 +- .../MetadataGenerationEnvironment.java | 4 + .../src/docs/asciidoc/running.adoc | 2 +- .../gradle/tasks/buildinfo/BuildInfo.java | 4 +- .../tasks/buildinfo/BuildInfoTests.java | 11 +- .../gradle/testkit/GradleBuild.java | 2 +- .../boot/ExitCodeGenerators.java | 20 +- .../boot/SpringApplication.java | 9 +- .../context/annotation/Configurations.java | 7 +- .../ConfigurationPropertiesBean.java | 12 +- .../boot/diagnostics/FailureAnalyzers.java | 4 +- ...eanCurrentlyInCreationFailureAnalyzer.java | 18 +- ...igurationPropertyValueFailureAnalyzer.java | 11 +- ...onfigurationPropertiesFailureAnalyzer.java | 13 +- ...NoUniqueBeanDefinitionFailureAnalyzer.java | 13 +- .../boot/jdbc/DatabaseDriver.java | 5 + .../context/LocalRSocketServerPort.java | 5 +- .../netty/NettyRSocketServerFactory.java | 16 +- .../MissingWebServerFactoryBeanException.java | 59 ---- ...ngWebServerFactoryBeanFailureAnalyzer.java | 47 --- .../jetty/JettyReactiveWebServerFactory.java | 4 +- .../jetty/JettyServletWebServerFactory.java | 2 +- .../netty/NettyReactiveWebServerFactory.java | 5 +- .../TomcatReactiveWebServerFactory.java | 2 +- .../tomcat/TomcatServletWebServerFactory.java | 2 +- .../UndertowWebServerFactoryDelegate.java | 5 +- .../ReactiveWebServerApplicationContext.java | 8 +- .../error/DefaultErrorAttributes.java | 7 +- .../server/ReactiveWebServerFactory.java | 5 +- .../AbstractConfigurableWebServerFactory.java | 15 +- .../CertificateFileSslStoreProvider.java | 118 ------- .../boot/web/server/CertificateParser.java | 109 ------- .../boot/web/server/LocalServerPort.java | 5 +- .../boot/web/server/PrivateKeyParser.java | 149 --------- .../springframework/boot/web/server/Ssl.java | 59 +--- .../ServletWebServerApplicationContext.java | 6 +- .../server/ServletWebServerFactory.java | 5 +- .../main/resources/META-INF/spring.factories | 1 - .../boot/ExitCodeGeneratorsTests.java | 35 +-- .../boot/SpringBootVersionTests.java | 2 +- .../ConfigurationPropertiesBeanTests.java | 21 -- ...rrentlyInCreationFailureAnalyzerTests.java | 21 +- ...tionPropertyValueFailureAnalyzerTests.java | 9 +- ...urationPropertiesFailureAnalyzerTests.java | 9 +- ...queBeanDefinitionFailureAnalyzerTests.java | 27 +- .../context/LocalRSocketServerPortTests.java | 3 +- .../netty/NettyRSocketServerFactoryTests.java | 42 --- ...ServerFactoryBeanFailureAnalyzerTests.java | 75 ----- .../TomcatServletWebServerFactoryTests.java | 13 +- ...ctiveWebServerApplicationContextTests.java | 2 +- ...AbstractReactiveWebServerFactoryTests.java | 23 +- .../CertificateFileSslStoreProviderTests.java | 133 -------- .../web/server/CertificateParserTests.java | 57 ---- .../boot/web/server/LocalServerPortTests.java | 3 +- .../web/server/PrivateKeyParserTests.java | 53 ---- .../AbstractServletWebServerFactoryTests.java | 28 -- .../src/test/resources/test-cert-chain.pem | 32 -- .../src/test/resources/test-cert.pem | 17 - .../src/test/resources/test-key.pem | 28 -- .../CustomServletPathSampleActuatorTests.java | 4 +- ...AndPathSampleActuatorApplicationTests.java | 6 +- ...tCustomServletPathSampleActuatorTests.java | 6 +- ...ctuatorCustomSecurityApplicationTests.java | 4 +- .../SampleActuatorUiApplicationPortTests.java | 6 +- ...AndPathSampleActuatorApplicationTests.java | 6 +- ...gementAddressActuatorApplicationTests.java | 6 +- ...entPortSampleActuatorApplicationTests.java | 4 +- ...entPortSampleActuatorApplicationTests.java | 6 +- ...gementPortWithLazyInitializationTests.java | 4 +- .../SampleOAuth2ClientApplicationTests.java | 4 +- .../profile/ActiveProfilesTests.java | 3 +- .../SampleRSocketApplicationTests.java | 4 +- .../src/main/resources/application.yml | 8 +- ...mpleSaml2RelyingPartyApplicationTests.java | 6 +- ...anagementPortSampleSecureWebFluxTests.java | 6 +- .../SampleSessionRedisApplicationTests.java | 2 - .../SampleSessionWebFluxApplicationTests.java | 2 +- ...leTomcatTwoConnectorsApplicationTests.java | 4 +- .../build.gradle | 13 - .../SampleWebApplicationTypeApplication.java | 29 -- .../src/main/resources/application.properties | 1 - ...denWebApplicationTypeApplicationTests.java | 44 --- ...pleWebApplicationTypeApplicationTests.java | 44 --- ...tNoneOverridesWebApplicationTypeTests.java | 48 --- .../SampleGroovyTemplateApplicationTests.java | 4 +- .../SampleMethodSecurityApplicationTests.java | 4 +- ...SampleWebSecureCustomApplicationTests.java | 4 +- .../SampleWebSecureJdbcApplicationTests.java | 4 +- .../SampleWebSecureApplicationTests.java | 4 +- .../SampleWebUiApplicationTests.java | 2 +- ...entPortSampleActuatorApplicationTests.java | 4 +- .../webservices/SampleWsApplicationTests.java | 4 +- .../SampleWebSocketsApplicationTests.java | 4 +- ...omContainerWebSocketsApplicationTests.java | 4 +- .../SampleWebSocketsApplicationTests.java | 4 +- ...omContainerWebSocketsApplicationTests.java | 4 +- .../SampleWebSocketsApplicationTests.java | 4 +- ...omContainerWebSocketsApplicationTests.java | 4 +- src/checkstyle/import-control.xml | 3 - 285 files changed, 1106 insertions(+), 6151 deletions(-) create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontProperties.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfiguration.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfiguration.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurations.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/TracingProperties.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/package-info.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/MeterRegistrySpanMetrics.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfiguration.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/package-info.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfiguration.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinProperties.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSender.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/package-info.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfiguration.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontProperties.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/package-info.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfigurationTests.java rename spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/{wavefront/WavefrontPropertiesMetricsExportTests.java => metrics/export/wavefront/WavefrontPropertiesTests.java} (58%) delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfigurationTests.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfigurationTests.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsMicrometerConfigurationTests.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsSdkConfigurationTests.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsTracerConfigurationTests.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/MeterRegistrySpanMetricsTests.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfigurationTests.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/NoopSender.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfigurationTests.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsBraveConfigurationTests.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsReporterConfigurationTests.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsSenderConfigurationTests.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSenderTests.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfigurationTests.java delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontPropertiesTests.java delete mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicator.java rename spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/{ElasticsearchRestClientHealthIndicatorTests.java => ElasticsearchRestHealthIndicatorTests.java} (90%) delete mode 100644 spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/rsocket/server/LocalRSocketServerPort.java delete mode 100644 spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/rsocket/server/package-info.java delete mode 100644 spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalManagementPort.java delete mode 100644 spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalServerPort.java delete mode 100644 spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/package-info.java delete mode 100644 spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/rsocket/server/LocalRSocketServerPortTests.java delete mode 100644 spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalManagementPortTests.java delete mode 100644 spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalServerPortTests.java delete mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanException.java delete mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzer.java delete mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/CertificateFileSslStoreProvider.java delete mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/CertificateParser.java delete mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PrivateKeyParser.java delete mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzerTests.java delete mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CertificateFileSslStoreProviderTests.java delete mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CertificateParserTests.java delete mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/PrivateKeyParserTests.java delete mode 100644 spring-boot-project/spring-boot/src/test/resources/test-cert-chain.pem delete mode 100644 spring-boot-project/spring-boot/src/test/resources/test-cert.pem delete mode 100644 spring-boot-project/spring-boot/src/test/resources/test-key.pem delete mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/build.gradle delete mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/main/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplication.java delete mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/main/resources/application.properties delete mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/OverriddenWebApplicationTypeApplicationTests.java delete mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplicationTests.java delete mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/WebEnvironmentNoneOverridesWebApplicationTypeTests.java diff --git a/buildSrc/src/main/java/org/springframework/boot/build/devtools/DocumentDevtoolsPropertyDefaults.java b/buildSrc/src/main/java/org/springframework/boot/build/devtools/DocumentDevtoolsPropertyDefaults.java index ef86b4a7ffd4..bb9ac2d52576 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/devtools/DocumentDevtoolsPropertyDefaults.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/devtools/DocumentDevtoolsPropertyDefaults.java @@ -41,7 +41,7 @@ */ public class DocumentDevtoolsPropertyDefaults extends DefaultTask { - private final Configuration devtools; + private Configuration devtools; private final RegularFileProperty outputFile; diff --git a/ci/images/ci-image-jdk18/Dockerfile b/ci/images/ci-image-jdk18/Dockerfile index 8dda41f84a65..08258db4cdca 100644 --- a/ci/images/ci-image-jdk18/Dockerfile +++ b/ci/images/ci-image-jdk18/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:focal-20220404 +FROM ubuntu:focal-20220316 ADD setup.sh /setup.sh ADD get-jdk-url.sh /get-jdk-url.sh diff --git a/ci/images/ci-image/Dockerfile b/ci/images/ci-image/Dockerfile index 68fd44c7b44d..254602311f76 100644 --- a/ci/images/ci-image/Dockerfile +++ b/ci/images/ci-image/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:focal-20220404 +FROM ubuntu:focal-20220316 ADD setup.sh /setup.sh ADD get-jdk-url.sh /get-jdk-url.sh diff --git a/gradle.properties b/gradle.properties index d3416ca15f3d..cf0f92064c7c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ org.gradle.caching=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8 -kotlinVersion=1.6.20 +kotlinVersion=1.6.20-RC2 tomcatVersion=10.0.18 kotlin.stdlib.default.dependency=false diff --git a/settings.gradle b/settings.gradle index d824aa229fb1..b2a608a6351f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -22,7 +22,7 @@ pluginManagement { } plugins { - id "com.gradle.enterprise" version "3.9" + id "com.gradle.enterprise" version "3.8.1" id "io.spring.ge.conventions" version "0.0.9" } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle b/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle index f8e30f8a1afc..04d9da39e855 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle @@ -50,9 +50,7 @@ dependencies { optional("io.micrometer:micrometer-observation") optional("io.micrometer:micrometer-core") optional("io.micrometer:micrometer-tracing-api") - optional("io.micrometer:micrometer-tracing-bridge-brave") - optional("io.micrometer:micrometer-tracing-bridge-otel") - optional("io.micrometer:micrometer-tracing-reporter-wavefront") + optional("io.micrometer:micrometer-binders") optional("io.micrometer:micrometer-registry-appoptics") optional("io.micrometer:micrometer-registry-atlas") { exclude group: "javax.inject", module: "javax.inject" @@ -78,8 +76,6 @@ dependencies { optional("io.micrometer:micrometer-registry-signalfx") optional("io.micrometer:micrometer-registry-statsd") optional("io.micrometer:micrometer-registry-wavefront") - optional("io.zipkin.reporter2:zipkin-sender-urlconnection") - optional("io.opentelemetry:opentelemetry-exporter-zipkin") optional("io.projectreactor.netty:reactor-netty-http") optional("io.r2dbc:r2dbc-pool") optional("io.r2dbc:r2dbc-spi") diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityService.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityService.java index 55d2cfd562da..7f9a83b3f15e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityService.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundrySecurityService.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -31,7 +31,6 @@ import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpStatus; -import org.springframework.http.HttpStatusCode; import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.util.Assert; import org.springframework.web.reactive.function.client.WebClient; @@ -91,7 +90,7 @@ Mono getAccessLevel(String token, String applicationId) throws Clou private Throwable mapError(Throwable throwable) { if (throwable instanceof WebClientResponseException) { - HttpStatusCode statusCode = ((WebClientResponseException) throwable).getStatusCode(); + HttpStatus statusCode = ((WebClientResponseException) throwable).getStatusCode(); if (statusCode.equals(HttpStatus.FORBIDDEN)) { return new CloudFoundryAuthorizationException(Reason.ACCESS_DENIED, "Access denied"); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfiguration.java index adc2194cd7ff..51e2b1e83f57 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfiguration.java @@ -22,7 +22,7 @@ import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration; import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestClientHealthIndicator; +import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestHealthIndicator; import org.springframework.boot.actuate.health.HealthContributor; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -34,21 +34,23 @@ /** * {@link EnableAutoConfiguration Auto-configuration} for - * {@link ElasticsearchRestClientHealthIndicator}. + * {@link ElasticsearchRestHealthIndicator} using the {@link RestClient}. * * @author Artsiom Yudovin * @since 2.1.1 */ +@SuppressWarnings("deprecation") @AutoConfiguration(after = ElasticsearchRestClientAutoConfiguration.class) -@ConditionalOnClass(RestClient.class) -@ConditionalOnBean(RestClient.class) +@ConditionalOnClass(org.elasticsearch.client.RestHighLevelClient.class) +@ConditionalOnBean(org.elasticsearch.client.RestHighLevelClient.class) @ConditionalOnEnabledHealthIndicator("elasticsearch") -public class ElasticSearchRestHealthContributorAutoConfiguration - extends CompositeHealthContributorConfiguration { +public class ElasticSearchRestHealthContributorAutoConfiguration extends + CompositeHealthContributorConfiguration { @Bean @ConditionalOnMissingBean(name = { "elasticsearchHealthIndicator", "elasticsearchHealthContributor" }) - public HealthContributor elasticsearchHealthContributor(Map clients) { + public HealthContributor elasticsearchHealthContributor( + Map clients) { return createContributor(clients); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfiguration.java index 929b7024bf97..4dca3308441f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfiguration.java @@ -16,12 +16,12 @@ package org.springframework.boot.actuate.autoconfigure.metrics; +import io.micrometer.binder.jvm.ClassLoaderMetrics; +import io.micrometer.binder.jvm.JvmGcMetrics; +import io.micrometer.binder.jvm.JvmHeapPressureMetrics; +import io.micrometer.binder.jvm.JvmMemoryMetrics; +import io.micrometer.binder.jvm.JvmThreadMetrics; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics; -import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics; -import io.micrometer.core.instrument.binder.jvm.JvmHeapPressureMetrics; -import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; -import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/KafkaMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/KafkaMetricsAutoConfiguration.java index fc5c39ca7771..31842b7e5826 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/KafkaMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/KafkaMetricsAutoConfiguration.java @@ -16,9 +16,9 @@ package org.springframework.boot.actuate.autoconfigure.metrics; +import io.micrometer.binder.kafka.KafkaClientMetrics; +import io.micrometer.binder.kafka.KafkaStreamsMetrics; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.binder.kafka.KafkaClientMetrics; -import io.micrometer.core.instrument.binder.kafka.KafkaStreamsMetrics; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfiguration.java index d2039e0466f9..f9a76f607206 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsAutoConfiguration.java @@ -16,8 +16,8 @@ package org.springframework.boot.actuate.autoconfigure.metrics; +import io.micrometer.binder.logging.Log4j2Metrics; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.binder.logging.Log4j2Metrics; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.spi.LoggerContext; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfiguration.java index 8a76340ff22a..1d1c19540b75 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfiguration.java @@ -17,8 +17,8 @@ package org.springframework.boot.actuate.autoconfigure.metrics; import ch.qos.logback.classic.LoggerContext; +import io.micrometer.binder.logging.LogbackMetrics; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.binder.logging.LogbackMetrics; import org.slf4j.ILoggerFactory; import org.slf4j.LoggerFactory; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfiguration.java index 30111b97e800..f113d7144384 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfiguration.java @@ -19,11 +19,11 @@ import java.io.File; import java.util.List; +import io.micrometer.binder.system.FileDescriptorMetrics; +import io.micrometer.binder.system.ProcessorMetrics; +import io.micrometer.binder.system.UptimeMetrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tags; -import io.micrometer.core.instrument.binder.system.FileDescriptorMetrics; -import io.micrometer.core.instrument.binder.system.ProcessorMetrics; -import io.micrometer.core.instrument.binder.system.UptimeMetrics; import org.springframework.boot.actuate.metrics.system.DiskSpaceMetricsBinder; import org.springframework.boot.autoconfigure.AutoConfiguration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsRegistrarConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsRegistrarConfiguration.java index 9c074c77da9b..d1b402ec36fb 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsRegistrarConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsRegistrarConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2020 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. @@ -72,7 +72,7 @@ private void bindCacheManagerToRegistry(String beanName, CacheManager cacheManag } private void bindCacheToRegistry(String beanName, Cache cache) { - Tag cacheManagerTag = Tag.of("cache.manager", getCacheManagerName(beanName)); + Tag cacheManagerTag = Tag.of("cacheManager", getCacheManagerName(beanName)); this.cacheMetricsRegistrar.bindCacheToRegistry(cache, cacheManagerTag); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceProperties.java index c1bd8ea930db..10a837b8895e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceProperties.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatraceProperties.java @@ -168,12 +168,6 @@ public static class V2 { */ private String metricKeyPrefix; - /** - * Whether to fall back to the built-in micrometer instruments for Timer and - * DistributionSummary. - */ - private boolean useDynatraceSummaryInstruments = true; - public Map getDefaultDimensions() { return this.defaultDimensions; } @@ -198,14 +192,6 @@ public void setMetricKeyPrefix(String metricKeyPrefix) { this.metricKeyPrefix = metricKeyPrefix; } - public boolean isUseDynatraceSummaryInstruments() { - return this.useDynatraceSummaryInstruments; - } - - public void setUseDynatraceSummaryInstruments(boolean useDynatraceSummaryInstruments) { - this.useDynatraceSummaryInstruments = useDynatraceSummaryInstruments; - } - } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapter.java index 82135f989860..6bcb21b9de93 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapter.java @@ -90,11 +90,6 @@ public boolean enrichWithDynatraceMetadata() { return get(v2(V2::isEnrichWithDynatraceMetadata), DynatraceConfig.super::enrichWithDynatraceMetadata); } - @Override - public boolean useDynatraceSummaryInstruments() { - return get(v2(V2::isUseDynatraceSummaryInstruments), DynatraceConfig.super::useDynatraceSummaryInstruments); - } - private Function v1(Function getter) { return (properties) -> getter.apply(properties.getV1()); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PropertiesConfigAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PropertiesConfigAdapter.java index 4cc34a988868..13e8a7af7bcc 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PropertiesConfigAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -31,7 +31,7 @@ */ public class PropertiesConfigAdapter { - private final T properties; + private T properties; /** * Create a new {@link PropertiesConfigAdapter} instance. diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfiguration.java index 386bec08d282..9524db72cfdf 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfiguration.java @@ -16,7 +16,10 @@ package org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront; +import java.time.Duration; + import com.wavefront.sdk.common.WavefrontSender; +import com.wavefront.sdk.common.clients.WavefrontClient.Builder; import io.micrometer.core.instrument.Clock; import io.micrometer.wavefront.WavefrontConfig; import io.micrometer.wavefront.WavefrontMeterRegistry; @@ -25,15 +28,16 @@ import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties; +import org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront.WavefrontProperties.Sender; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.context.annotation.Bean; +import org.springframework.util.unit.DataSize; /** * {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to Wavefront. @@ -45,17 +49,29 @@ */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, - after = { MetricsAutoConfiguration.class, WavefrontAutoConfiguration.class }) -@ConditionalOnBean({ Clock.class, WavefrontSender.class }) + after = MetricsAutoConfiguration.class) +@ConditionalOnBean(Clock.class) @ConditionalOnClass({ WavefrontMeterRegistry.class, WavefrontSender.class }) @ConditionalOnEnabledMetricsExport("wavefront") @EnableConfigurationProperties(WavefrontProperties.class) public class WavefrontMetricsExportAutoConfiguration { + private final WavefrontProperties properties; + + public WavefrontMetricsExportAutoConfiguration(WavefrontProperties properties) { + this.properties = properties; + } + + @Bean + @ConditionalOnMissingBean + public WavefrontConfig wavefrontConfig() { + return new WavefrontPropertiesConfigAdapter(this.properties); + } + @Bean @ConditionalOnMissingBean - public WavefrontConfig wavefrontConfig(WavefrontProperties properties) { - return new WavefrontPropertiesConfigAdapter(properties); + public WavefrontSender wavefrontSender(WavefrontConfig wavefrontConfig) { + return createWavefrontSender(wavefrontConfig); } @Bean @@ -65,4 +81,14 @@ public WavefrontMeterRegistry wavefrontMeterRegistry(WavefrontConfig wavefrontCo return WavefrontMeterRegistry.builder(wavefrontConfig).clock(clock).wavefrontSender(wavefrontSender).build(); } + private WavefrontSender createWavefrontSender(WavefrontConfig wavefrontConfig) { + Builder builder = WavefrontMeterRegistry.getDefaultSenderBuilder(wavefrontConfig); + PropertyMapper mapper = PropertyMapper.get().alwaysApplyingWhenNonNull(); + Sender sender = this.properties.getSender(); + mapper.from(sender.getMaxQueueSize()).to(builder::maxQueueSize); + mapper.from(sender.getFlushInterval()).asInt(Duration::getSeconds).to(builder::flushIntervalSeconds); + mapper.from(sender.getMessageSize()).asInt(DataSize::toBytes).to(builder::messageSizeBytes); + return builder.build(); + } + } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontProperties.java new file mode 100644 index 000000000000..0d3949c6b864 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontProperties.java @@ -0,0 +1,132 @@ +/* + * Copyright 2012-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.boot.actuate.autoconfigure.metrics.export.wavefront; + +import java.net.URI; +import java.time.Duration; + +import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PushRegistryProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.util.unit.DataSize; + +/** + * {@link ConfigurationProperties @ConfigurationProperties} for configuring Wavefront + * metrics export. + * + * @author Jon Schneider + * @author Stephane Nicoll + * @since 2.0.0 + */ +@ConfigurationProperties("management.wavefront.metrics.export") +public class WavefrontProperties extends PushRegistryProperties { + + /** + * URI to ship metrics to. + */ + private URI uri = URI.create("https://longboard.wavefront.com"); + + /** + * Unique identifier for the app instance that is the source of metrics being + * published to Wavefront. Defaults to the local host name. + */ + private String source; + + /** + * API token used when publishing metrics directly to the Wavefront API host. + */ + private String apiToken; + + /** + * Global prefix to separate metrics originating from this app's white box + * instrumentation from those originating from other Wavefront integrations when + * viewed in the Wavefront UI. + */ + private String globalPrefix; + + private final Sender sender = new Sender(); + + public URI getUri() { + return this.uri; + } + + public void setUri(URI uri) { + this.uri = uri; + } + + public String getSource() { + return this.source; + } + + public void setSource(String source) { + this.source = source; + } + + public String getApiToken() { + return this.apiToken; + } + + public void setApiToken(String apiToken) { + this.apiToken = apiToken; + } + + public String getGlobalPrefix() { + return this.globalPrefix; + } + + public void setGlobalPrefix(String globalPrefix) { + this.globalPrefix = globalPrefix; + } + + public Sender getSender() { + return this.sender; + } + + public static class Sender { + + private int maxQueueSize = 50000; + + private Duration flushInterval = Duration.ofSeconds(1); + + private DataSize messageSize = DataSize.ofBytes(Integer.MAX_VALUE); + + public int getMaxQueueSize() { + return this.maxQueueSize; + } + + public void setMaxQueueSize(int maxQueueSize) { + this.maxQueueSize = maxQueueSize; + } + + public Duration getFlushInterval() { + return this.flushInterval; + } + + public void setFlushInterval(Duration flushInterval) { + this.flushInterval = flushInterval; + } + + public DataSize getMessageSize() { + return this.messageSize; + } + + public void setMessageSize(DataSize messageSize) { + this.messageSize = messageSize; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapter.java index 8422593ff124..a46e5c4ee5bc 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapter.java @@ -19,24 +19,18 @@ import io.micrometer.wavefront.WavefrontConfig; import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PushRegistryPropertiesConfigAdapter; -import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties; -import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties.Metrics.Export; /** - * Adapter to convert {@link WavefrontProperties.Metrics} to a {@link WavefrontConfig}. + * Adapter to convert {@link WavefrontProperties} to a {@link WavefrontConfig}. * * @author Jon Schneider - * @author Moritz Halbritter * @since 2.0.0 */ -public class WavefrontPropertiesConfigAdapter - extends PushRegistryPropertiesConfigAdapter implements WavefrontConfig { - - private final WavefrontProperties properties; +public class WavefrontPropertiesConfigAdapter extends PushRegistryPropertiesConfigAdapter + implements WavefrontConfig { public WavefrontPropertiesConfigAdapter(WavefrontProperties properties) { - super(properties.getMetrics().getExport()); - this.properties = properties; + super(properties); } @Override @@ -45,28 +39,32 @@ public String prefix() { } @Override - public String uri() { - return this.properties.getEffectiveUri().toString(); + public String get(String k) { + return null; } @Override - public String source() { - return this.properties.getSourceOrDefault(); + public String uri() { + return get(this::getUriAsString, WavefrontConfig.DEFAULT_DIRECT::uri); } @Override - public int batchSize() { - return this.properties.getSender().getBatchSize(); + public String source() { + return get(WavefrontProperties::getSource, WavefrontConfig.super::source); } @Override public String apiToken() { - return this.properties.getApiTokenOrThrow(); + return get(WavefrontProperties::getApiToken, WavefrontConfig.super::apiToken); } @Override public String globalPrefix() { - return get(Export::getGlobalPrefix, WavefrontConfig.super::globalPrefix); + return get(WavefrontProperties::getGlobalPrefix, WavefrontConfig.super::globalPrefix); + } + + private String getUriAsString(WavefrontProperties properties) { + return (properties.getUri() != null) ? properties.getUri().toString() : null; } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration.java index 8816f91ce557..c78bea92e5e1 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration.java @@ -28,11 +28,11 @@ import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.metrics.micrometer.MicrometerMetricsTrackerFactory; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.binder.MeterBinder; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.actuate.metrics.jdbc.DataSourcePoolMetrics; @@ -43,7 +43,6 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.jdbc.DataSourceUnwrapper; import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadataProvider; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.log.LogMessage; import org.springframework.util.StringUtils; @@ -67,52 +66,33 @@ static class DataSourcePoolMetadataMetricsConfiguration { private static final String DATASOURCE_SUFFIX = "dataSource"; - @Bean - DataSourcePoolMetadataMeterBinder dataSourcePoolMetadataMeterBinder(Map dataSources, + @Autowired + void bindDataSourcesToRegistry(Map dataSources, MeterRegistry registry, ObjectProvider metadataProviders) { - return new DataSourcePoolMetadataMeterBinder(dataSources, metadataProviders); + List metadataProvidersList = metadataProviders.stream() + .collect(Collectors.toList()); + dataSources.forEach( + (name, dataSource) -> bindDataSourceToRegistry(name, dataSource, metadataProvidersList, registry)); } - static class DataSourcePoolMetadataMeterBinder implements MeterBinder { - - private final Map dataSources; - - private final ObjectProvider metadataProviders; - - DataSourcePoolMetadataMeterBinder(Map dataSources, - ObjectProvider metadataProviders) { - this.dataSources = dataSources; - this.metadataProviders = metadataProviders; - } - - @Override - public void bindTo(MeterRegistry registry) { - List metadataProvidersList = this.metadataProviders.stream() - .collect(Collectors.toList()); - this.dataSources.forEach((name, dataSource) -> bindDataSourceToRegistry(name, dataSource, - metadataProvidersList, registry)); - } - - private void bindDataSourceToRegistry(String beanName, DataSource dataSource, - Collection metadataProviders, MeterRegistry registry) { - String dataSourceName = getDataSourceName(beanName); - new DataSourcePoolMetrics(dataSource, metadataProviders, dataSourceName, Collections.emptyList()) - .bindTo(registry); - } + private void bindDataSourceToRegistry(String beanName, DataSource dataSource, + Collection metadataProviders, MeterRegistry registry) { + String dataSourceName = getDataSourceName(beanName); + new DataSourcePoolMetrics(dataSource, metadataProviders, dataSourceName, Collections.emptyList()) + .bindTo(registry); + } - /** - * Get the name of a DataSource based on its {@code beanName}. - * @param beanName the name of the data source bean - * @return a name for the given data source - */ - private String getDataSourceName(String beanName) { - if (beanName.length() > DATASOURCE_SUFFIX.length() - && StringUtils.endsWithIgnoreCase(beanName, DATASOURCE_SUFFIX)) { - return beanName.substring(0, beanName.length() - DATASOURCE_SUFFIX.length()); - } - return beanName; + /** + * Get the name of a DataSource based on its {@code beanName}. + * @param beanName the name of the data source bean + * @return a name for the given data source + */ + private String getDataSourceName(String beanName) { + if (beanName.length() > DATASOURCE_SUFFIX.length() + && StringUtils.endsWithIgnoreCase(beanName, DATASOURCE_SUFFIX)) { + return beanName.substring(0, beanName.length() - DATASOURCE_SUFFIX.length()); } - + return beanName; } } @@ -121,43 +101,34 @@ private String getDataSourceName(String beanName) { @ConditionalOnClass(HikariDataSource.class) static class HikariDataSourceMetricsConfiguration { - @Bean - HikariDataSourceMeterBinder hikariDataSourceMeterBinder(ObjectProvider dataSources) { - return new HikariDataSourceMeterBinder(dataSources); - } - - static class HikariDataSourceMeterBinder implements MeterBinder { + private static final Log logger = LogFactory.getLog(HikariDataSourceMetricsConfiguration.class); - private static final Log logger = LogFactory.getLog(HikariDataSourceMeterBinder.class); + private final MeterRegistry registry; - private final ObjectProvider dataSources; - - HikariDataSourceMeterBinder(ObjectProvider dataSources) { - this.dataSources = dataSources; - } + HikariDataSourceMetricsConfiguration(MeterRegistry registry) { + this.registry = registry; + } - @Override - public void bindTo(MeterRegistry registry) { - for (DataSource dataSource : this.dataSources) { - HikariDataSource hikariDataSource = DataSourceUnwrapper.unwrap(dataSource, HikariConfigMXBean.class, - HikariDataSource.class); - if (hikariDataSource != null) { - bindMetricsRegistryToHikariDataSource(hikariDataSource, registry); - } + @Autowired + void bindMetricsRegistryToHikariDataSources(Collection dataSources) { + for (DataSource dataSource : dataSources) { + HikariDataSource hikariDataSource = DataSourceUnwrapper.unwrap(dataSource, HikariConfigMXBean.class, + HikariDataSource.class); + if (hikariDataSource != null) { + bindMetricsRegistryToHikariDataSource(hikariDataSource); } } + } - private void bindMetricsRegistryToHikariDataSource(HikariDataSource hikari, MeterRegistry registry) { - if (hikari.getMetricRegistry() == null && hikari.getMetricsTrackerFactory() == null) { - try { - hikari.setMetricsTrackerFactory(new MicrometerMetricsTrackerFactory(registry)); - } - catch (Exception ex) { - logger.warn(LogMessage.format("Failed to bind Hikari metrics: %s", ex.getMessage())); - } + private void bindMetricsRegistryToHikariDataSource(HikariDataSource hikari) { + if (hikari.getMetricRegistry() == null && hikari.getMetricsTrackerFactory() == null) { + try { + hikari.setMetricsTrackerFactory(new MicrometerMetricsTrackerFactory(this.registry)); + } + catch (Exception ex) { + logger.warn(LogMessage.format("Failed to bind Hikari metrics: %s", ex.getMessage())); } } - } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfiguration.java index 1e448b46f0ed..4c66f9dd92f5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfiguration.java @@ -17,13 +17,13 @@ package org.springframework.boot.actuate.autoconfigure.metrics.mongo; import com.mongodb.MongoClientSettings; +import io.micrometer.binder.mongodb.DefaultMongoCommandTagsProvider; +import io.micrometer.binder.mongodb.DefaultMongoConnectionPoolTagsProvider; +import io.micrometer.binder.mongodb.MongoCommandTagsProvider; +import io.micrometer.binder.mongodb.MongoConnectionPoolTagsProvider; +import io.micrometer.binder.mongodb.MongoMetricsCommandListener; +import io.micrometer.binder.mongodb.MongoMetricsConnectionPoolListener; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.binder.mongodb.DefaultMongoCommandTagsProvider; -import io.micrometer.core.instrument.binder.mongodb.DefaultMongoConnectionPoolTagsProvider; -import io.micrometer.core.instrument.binder.mongodb.MongoCommandTagsProvider; -import io.micrometer.core.instrument.binder.mongodb.MongoConnectionPoolTagsProvider; -import io.micrometer.core.instrument.binder.mongodb.MongoMetricsCommandListener; -import io.micrometer.core.instrument.binder.mongodb.MongoMetricsConnectionPoolListener; import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfiguration.java index e530be89bc95..be30193c2cc5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/task/TaskExecutorMetricsAutoConfiguration.java @@ -21,8 +21,8 @@ import java.util.concurrent.Executor; import java.util.concurrent.ThreadPoolExecutor; +import io.micrometer.binder.jvm.ExecutorServiceMetrics; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.binder.jvm.ExecutorServiceMetrics; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfiguration.java index 4bd6eb69bfcd..7b6cc708da8a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/jetty/JettyMetricsAutoConfiguration.java @@ -16,10 +16,10 @@ package org.springframework.boot.actuate.autoconfigure.metrics.web.jetty; +import io.micrometer.binder.jetty.JettyConnectionMetrics; +import io.micrometer.binder.jetty.JettyServerThreadPoolMetrics; +import io.micrometer.binder.jetty.JettySslHandshakeMetrics; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.binder.jetty.JettyConnectionMetrics; -import io.micrometer.core.instrument.binder.jetty.JettyServerThreadPoolMetrics; -import io.micrometer.core.instrument.binder.jetty.JettySslHandshakeMetrics; import org.eclipse.jetty.server.Server; import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfiguration.java index b5818258b87d..c81aeb62c4af 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfiguration.java @@ -16,8 +16,8 @@ package org.springframework.boot.actuate.autoconfigure.metrics.web.tomcat; +import io.micrometer.binder.tomcat.TomcatMetrics; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.binder.tomcat.TomcatMetrics; import org.apache.catalina.Manager; import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java index c0114bf211f1..1b0f9c420512 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java @@ -17,7 +17,7 @@ package org.springframework.boot.actuate.autoconfigure.observation; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.observation.Observation.GlobalKeyValuesProvider; +import io.micrometer.observation.Observation.GlobalTagsProvider; import io.micrometer.observation.ObservationHandler; import io.micrometer.observation.ObservationPredicate; import io.micrometer.observation.ObservationRegistry; @@ -48,7 +48,7 @@ public class ObservationAutoConfiguration { static ObservationRegistryPostProcessor observationRegistryPostProcessor( ObjectProvider> observationRegistryCustomizers, ObjectProvider observationPredicates, - ObjectProvider> tagProviders, + ObjectProvider> tagProviders, ObjectProvider> observationHandlers, ObjectProvider observationHandlerGrouping) { return new ObservationRegistryPostProcessor(observationRegistryCustomizers, observationPredicates, tagProviders, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryConfigurer.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryConfigurer.java index 83cb91eb837a..e4f0c88d35f6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryConfigurer.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryConfigurer.java @@ -18,7 +18,7 @@ import java.util.List; -import io.micrometer.observation.Observation.GlobalKeyValuesProvider; +import io.micrometer.observation.Observation.GlobalTagsProvider; import io.micrometer.observation.ObservationHandler; import io.micrometer.observation.ObservationPredicate; import io.micrometer.observation.ObservationRegistry; @@ -29,7 +29,7 @@ /** * Configurer to apply {@link ObservationRegistryCustomizer customizers} to * {@link ObservationRegistry observation registries}. Installs - * {@link ObservationPredicate observation predicates} and {@link GlobalKeyValuesProvider + * {@link ObservationPredicate observation predicates} and {@link GlobalTagsProvider * global tag providers} into the {@link ObservationRegistry}. Also uses a * {@link ObservationHandlerGrouping} to group handlers, which are then added to the * {@link ObservationRegistry}. @@ -42,7 +42,7 @@ class ObservationRegistryConfigurer { private final ObjectProvider observationPredicates; - private final ObjectProvider> tagProviders; + private final ObjectProvider> tagProviders; private final ObjectProvider> observationHandlers; @@ -50,7 +50,7 @@ class ObservationRegistryConfigurer { ObservationRegistryConfigurer(ObjectProvider> customizers, ObjectProvider observationPredicates, - ObjectProvider> tagProviders, + ObjectProvider> tagProviders, ObjectProvider> observationHandlers, ObjectProvider observationHandlerGrouping) { this.customizers = customizers; @@ -79,7 +79,7 @@ private void registerObservationPredicates(ObservationRegistry registry) { private void registerGlobalTagsProvider(ObservationRegistry registry) { this.tagProviders.orderedStream() - .forEach((tagProvider) -> registry.observationConfig().keyValuesProvider(tagProvider)); + .forEach((tagProvider) -> registry.observationConfig().tagsProvider(tagProvider)); } @SuppressWarnings("unchecked") diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryPostProcessor.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryPostProcessor.java index baa1ca0d3374..c3404c1fd8f1 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryPostProcessor.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationRegistryPostProcessor.java @@ -16,7 +16,7 @@ package org.springframework.boot.actuate.autoconfigure.observation; -import io.micrometer.observation.Observation.GlobalKeyValuesProvider; +import io.micrometer.observation.Observation.GlobalTagsProvider; import io.micrometer.observation.ObservationHandler; import io.micrometer.observation.ObservationPredicate; import io.micrometer.observation.ObservationRegistry; @@ -38,7 +38,7 @@ class ObservationRegistryPostProcessor implements BeanPostProcessor { private final ObjectProvider observationPredicates; - private final ObjectProvider> tagProviders; + private final ObjectProvider> tagProviders; private final ObjectProvider> observationHandlers; @@ -48,7 +48,7 @@ class ObservationRegistryPostProcessor implements BeanPostProcessor { ObservationRegistryPostProcessor(ObjectProvider> observationRegistryCustomizers, ObjectProvider observationPredicates, - ObjectProvider> tagProviders, + ObjectProvider> tagProviders, ObjectProvider> observationHandlers, ObjectProvider observationHandlerGrouping) { this.observationRegistryCustomizers = observationRegistryCustomizers; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java deleted file mode 100644 index e084680152af..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing; - -import java.util.List; - -import brave.Tracing; -import brave.Tracing.Builder; -import brave.TracingCustomizer; -import brave.handler.SpanHandler; -import brave.propagation.B3Propagation; -import brave.propagation.CurrentTraceContext; -import brave.propagation.CurrentTraceContext.ScopeDecorator; -import brave.propagation.CurrentTraceContextCustomizer; -import brave.propagation.Propagation.Factory; -import brave.propagation.ThreadLocalCurrentTraceContext; -import brave.sampler.Sampler; -import io.micrometer.tracing.brave.bridge.BraveBaggageManager; -import io.micrometer.tracing.brave.bridge.BraveCurrentTraceContext; -import io.micrometer.tracing.brave.bridge.BraveTracer; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for Brave. - * - * @author Moritz Halbritter - * @since 3.0.0 - */ -@AutoConfiguration(before = MicrometerTracingAutoConfiguration.class) -@ConditionalOnClass(brave.Tracer.class) -@EnableConfigurationProperties(TracingProperties.class) -public class BraveAutoConfiguration { - - /** - * Default value for application name if {@code spring.application.name} is not set. - */ - private static final String DEFAULT_APPLICATION_NAME = "application"; - - @Bean - @ConditionalOnMissingBean - public Tracing braveTracing(Environment environment, List spanHandlers, - List tracingCustomizers, CurrentTraceContext currentTraceContext, - Factory propagationFactory, Sampler sampler) { - String applicationName = environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME); - Builder builder = Tracing.newBuilder().currentTraceContext(currentTraceContext) - .propagationFactory(propagationFactory).sampler(sampler).localServiceName(applicationName); - for (SpanHandler spanHandler : spanHandlers) { - builder.addSpanHandler(spanHandler); - } - for (TracingCustomizer tracingCustomizer : tracingCustomizers) { - tracingCustomizer.customize(builder); - } - return builder.build(); - } - - @Bean - @ConditionalOnMissingBean - public brave.Tracer braveTracer(Tracing tracing) { - return tracing.tracer(); - } - - @Bean - @ConditionalOnMissingBean - public CurrentTraceContext braveCurrentTraceContext(List scopeDecorators, - List currentTraceContextCustomizers) { - ThreadLocalCurrentTraceContext.Builder builder = ThreadLocalCurrentTraceContext.newBuilder(); - for (ScopeDecorator scopeDecorator : scopeDecorators) { - builder.addScopeDecorator(scopeDecorator); - } - for (CurrentTraceContextCustomizer currentTraceContextCustomizer : currentTraceContextCustomizers) { - currentTraceContextCustomizer.customize(builder); - } - return builder.build(); - } - - @Bean - @ConditionalOnMissingBean - public Factory bravePropagationFactory() { - return B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build(); - } - - @Bean - @ConditionalOnMissingBean - public Sampler braveSampler(TracingProperties properties) { - return Sampler.create(properties.getSampling().getProbability()); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(BraveTracer.class) - static class BraveMicrometer { - - @Bean - @ConditionalOnMissingBean - BraveTracer braveTracerBridge(brave.Tracer tracer, CurrentTraceContext currentTraceContext, - BraveBaggageManager braveBaggageManager) { - return new BraveTracer(tracer, new BraveCurrentTraceContext(currentTraceContext), braveBaggageManager); - } - - @Bean - @ConditionalOnMissingBean - BraveBaggageManager braveBaggageManager() { - return new BraveBaggageManager(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfiguration.java deleted file mode 100644 index 5d279b54c2f5..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfiguration.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing; - -import io.micrometer.tracing.Tracer; -import io.micrometer.tracing.handler.DefaultTracingObservationHandler; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for the Micrometer Tracing API. - * - * @author Moritz Halbritter - * @since 3.0.0 - */ -@AutoConfiguration -@ConditionalOnClass(Tracer.class) -public class MicrometerTracingAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - @ConditionalOnBean(Tracer.class) - public DefaultTracingObservationHandler defaultTracingObservationHandler(Tracer tracer) { - return new DefaultTracingObservationHandler(tracer); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfiguration.java deleted file mode 100644 index 006eaf39b658..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfiguration.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing; - -import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.MicrometerConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.SdkConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.TracerConfiguration; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.context.annotation.Import; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for OpenTelemetry. - * - * It uses imports on {@link OpenTelemetryConfigurations} to guarantee the correct - * configuration ordering. - * - * @author Moritz Halbritter - * @since 3.0.0 - */ -@AutoConfiguration(before = MicrometerTracingAutoConfiguration.class) -@Import({ SdkConfiguration.class, TracerConfiguration.class, MicrometerConfiguration.class }) -public class OpenTelemetryAutoConfiguration { - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurations.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurations.java deleted file mode 100644 index fe95f30916ad..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurations.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing; - -import java.util.List; -import java.util.stream.Collectors; - -import io.micrometer.tracing.otel.bridge.OtelBaggageManager; -import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext; -import io.micrometer.tracing.otel.bridge.OtelTracer; -import io.micrometer.tracing.otel.bridge.OtelTracer.EventPublisher; -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.context.propagation.ContextPropagators; -import io.opentelemetry.context.propagation.TextMapPropagator; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.trace.SdkTracerProvider; -import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; -import io.opentelemetry.sdk.trace.SpanProcessor; -import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import io.opentelemetry.sdk.trace.samplers.Sampler; -import io.opentelemetry.semconv.resource.attributes.ResourceAttributes; - -import org.springframework.boot.SpringBootVersion; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; - -/** - * Configurations for Open Telemetry. Those are imported by - * {@link OpenTelemetryAutoConfiguration}. - * - * @author Moritz Halbritter - */ -class OpenTelemetryConfigurations { - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(SdkTracerProvider.class) - @EnableConfigurationProperties(TracingProperties.class) - static class SdkConfiguration { - - /** - * Default value for application name if {@code spring.application.name} is not - * set. - */ - private static final String DEFAULT_APPLICATION_NAME = "application"; - - @Bean - @ConditionalOnMissingBean - OpenTelemetry openTelemetry(SdkTracerProvider sdkTracerProvider, ContextPropagators contextPropagators) { - return OpenTelemetrySdk.builder().setTracerProvider(sdkTracerProvider).setPropagators(contextPropagators) - .build(); - } - - @Bean - @ConditionalOnMissingBean - SdkTracerProvider otelSdkTracerProvider(Environment environment, List spanProcessors, - Sampler sampler) { - String applicationName = environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME); - SdkTracerProviderBuilder builder = SdkTracerProvider.builder().setSampler(sampler) - .setResource(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, applicationName))); - for (SpanProcessor spanProcessor : spanProcessors) { - builder.addSpanProcessor(spanProcessor); - } - return builder.build(); - } - - @Bean - @ConditionalOnMissingBean - ContextPropagators otelContextPropagators(List textMapPropagators) { - return ContextPropagators.create(TextMapPropagator.composite(textMapPropagators)); - } - - @Bean - @ConditionalOnMissingBean - Sampler otelSampler(TracingProperties properties) { - return Sampler.traceIdRatioBased(properties.getSampling().getProbability()); - } - - @Bean - @ConditionalOnMissingBean - SpanProcessor otelSpanProcessor(List spanExporter) { - return SpanProcessor.composite(spanExporter.stream() - .map((exporter) -> BatchSpanProcessor.builder(exporter).build()).collect(Collectors.toList())); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(Tracer.class) - static class TracerConfiguration { - - @Bean - @ConditionalOnMissingBean - @ConditionalOnBean(OpenTelemetry.class) - Tracer otelTracer(OpenTelemetry openTelemetry) { - return openTelemetry.getTracer("org.springframework.boot", SpringBootVersion.getVersion()); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(OtelTracer.class) - static class MicrometerConfiguration { - - @Bean - @ConditionalOnMissingBean - @ConditionalOnBean(Tracer.class) - OtelTracer micrometerOtelTracer(Tracer tracer, EventPublisher eventPublisher, - OtelCurrentTraceContext otelCurrentTraceContext) { - return new OtelTracer(tracer, otelCurrentTraceContext, eventPublisher, - new OtelBaggageManager(otelCurrentTraceContext, List.of(), List.of())); - } - - @Bean - @ConditionalOnMissingBean - EventPublisher otelTracerEventPublisher() { - return (event) -> { - }; - } - - @Bean - @ConditionalOnMissingBean - OtelCurrentTraceContext otelCurrentTraceContext() { - return new OtelCurrentTraceContext(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/TracingProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/TracingProperties.java deleted file mode 100644 index 56ce52a93a5a..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/TracingProperties.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * Configuration properties for tracing. - * - * @author Moritz Halbritter - * @since 3.0.0 - */ -@ConfigurationProperties("management.tracing") -public class TracingProperties { - - /** - * Sampling configuration. - */ - private final Sampling sampling = new Sampling(); - - public Sampling getSampling() { - return this.sampling; - } - - public static class Sampling { - - /** - * Probability in the range from 0.0 to 1.0 that a trace will be sampled. - */ - private float probability = 0.10f; - - public float getProbability() { - return this.probability; - } - - public void setProbability(float probability) { - this.probability = probability; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/package-info.java deleted file mode 100644 index 64e6f7cad706..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-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. - */ - -/** - * Auto-configuration for Micrometer Tracing. - */ -package org.springframework.boot.actuate.autoconfigure.tracing; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/MeterRegistrySpanMetrics.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/MeterRegistrySpanMetrics.java deleted file mode 100644 index 1f9d4e0325e3..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/MeterRegistrySpanMetrics.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing.wavefront; - -import java.util.concurrent.BlockingQueue; - -import io.micrometer.core.instrument.Counter; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.tracing.reporter.wavefront.SpanMetrics; - -/** - * Bridges {@link SpanMetrics} to a {@link MeterRegistry}. - * - * @author Moritz Halbritter - */ -class MeterRegistrySpanMetrics implements SpanMetrics { - - private final Counter spansReceived; - - private final Counter spansDropped; - - private final Counter reportErrors; - - private final MeterRegistry meterRegistry; - - MeterRegistrySpanMetrics(MeterRegistry meterRegistry) { - this.meterRegistry = meterRegistry; - this.spansReceived = meterRegistry.counter("wavefront.reporter.spans.received"); - this.spansDropped = meterRegistry.counter("wavefront.reporter.spans.dropped"); - this.reportErrors = meterRegistry.counter("wavefront.reporter.errors"); - } - - @Override - public void reportDropped() { - this.spansDropped.increment(); - } - - @Override - public void reportReceived() { - this.spansReceived.increment(); - } - - @Override - public void reportErrors() { - this.reportErrors.increment(); - } - - @Override - public void registerQueueSize(BlockingQueue queue) { - this.meterRegistry.gauge("wavefront.reporter.queue.size", queue, (q) -> (double) q.size()); - } - - @Override - public void registerQueueRemainingCapacity(BlockingQueue queue) { - this.meterRegistry.gauge("wavefront.reporter.queue.remaining_capacity", queue, - (q) -> (double) q.remainingCapacity()); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfiguration.java deleted file mode 100644 index 9eea91397ac4..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfiguration.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing.wavefront; - -import java.util.Set; - -import brave.handler.SpanHandler; -import com.wavefront.sdk.common.WavefrontSender; -import com.wavefront.sdk.common.application.ApplicationTags; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.tracing.reporter.wavefront.SpanMetrics; -import io.micrometer.tracing.reporter.wavefront.WavefrontBraveSpanHandler; -import io.micrometer.tracing.reporter.wavefront.WavefrontOtelSpanHandler; -import io.micrometer.tracing.reporter.wavefront.WavefrontSpanHandler; -import io.opentelemetry.sdk.trace.export.SpanExporter; - -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties; -import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties.Tracing; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for Wavefront. - * - * @author Moritz Halbritter - * @since 3.0.0 - */ -@AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class, - WavefrontAutoConfiguration.class }) -@EnableConfigurationProperties(WavefrontProperties.class) -@ConditionalOnBean(WavefrontSender.class) -public class WavefrontTracingAutoConfiguration { - - /** - * Default value for application name if {@code spring.application.name} is not set. - */ - private static final String DEFAULT_APPLICATION_NAME = "application"; - - @Bean - @ConditionalOnMissingBean - public ApplicationTags applicationTags(Environment environment, WavefrontProperties properties) { - String springApplicationName = environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME); - Tracing tracing = properties.getTracing(); - String applicationName = (tracing.getApplicationName() != null) ? tracing.getApplicationName() - : springApplicationName; - String serviceName = (tracing.getServiceName() != null) ? tracing.getServiceName() : springApplicationName; - return new ApplicationTags.Builder(applicationName, serviceName).build(); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(WavefrontSpanHandler.class) - static class WavefrontMicrometer { - - @Bean - @ConditionalOnMissingBean - WavefrontSpanHandler wavefrontSpanHandler(WavefrontProperties properties, WavefrontSender wavefrontSender, - SpanMetrics spanMetrics, ApplicationTags applicationTags) { - return new WavefrontSpanHandler(properties.getSender().getMaxQueueSize(), wavefrontSender, spanMetrics, - properties.getSourceOrDefault(), applicationTags, Set.of()); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnBean(MeterRegistry.class) - static class MeterRegistrySpanMetricsConfiguration { - - @Bean - @ConditionalOnMissingBean - MeterRegistrySpanMetrics meterRegistrySpanMetrics(MeterRegistry meterRegistry) { - return new MeterRegistrySpanMetrics(meterRegistry); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnMissingBean(MeterRegistry.class) - static class NoopSpanMetricsConfiguration { - - @Bean - @ConditionalOnMissingBean - SpanMetrics meterRegistrySpanMetrics() { - return SpanMetrics.NOOP; - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(SpanHandler.class) - static class WavefrontBrave { - - @Bean - @ConditionalOnMissingBean - WavefrontBraveSpanHandler wavefrontBraveSpanHandler(WavefrontSpanHandler wavefrontSpanHandler) { - return new WavefrontBraveSpanHandler(wavefrontSpanHandler); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(SpanExporter.class) - static class WavefrontOpenTelemetry { - - @Bean - @ConditionalOnMissingBean - WavefrontOtelSpanHandler wavefrontOtelSpanHandler(WavefrontSpanHandler wavefrontSpanHandler) { - return new WavefrontOtelSpanHandler(wavefrontSpanHandler); - } - - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/package-info.java deleted file mode 100644 index 5ded81bd8e2f..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-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. - */ - -/** - * Auto-configuration for tracing with Wavefront. - */ -package org.springframework.boot.actuate.autoconfigure.tracing.wavefront; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfiguration.java deleted file mode 100644 index 89862e4e6635..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfiguration.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; - -import zipkin2.Span; -import zipkin2.codec.BytesEncoder; -import zipkin2.codec.SpanBytesEncoder; -import zipkin2.reporter.Sender; - -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.BraveConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.OpenTelemetryConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.ReporterConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.SenderConfiguration; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for Zipkin. - * - * It uses imports on {@link ZipkinConfigurations} to guarantee the correct configuration - * ordering. - * - * @author Moritz Halbritter - * @since 3.0.0 - */ -@AutoConfiguration(after = RestTemplateAutoConfiguration.class) -@ConditionalOnClass(Sender.class) -@Import({ SenderConfiguration.class, ReporterConfiguration.class, BraveConfiguration.class, - OpenTelemetryConfiguration.class }) -public class ZipkinAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - public BytesEncoder spanBytesEncoder() { - return SpanBytesEncoder.JSON_V2; - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java deleted file mode 100644 index cd7c96347fec..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; - -import brave.handler.SpanHandler; -import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; -import zipkin2.Span; -import zipkin2.codec.BytesEncoder; -import zipkin2.reporter.AsyncReporter; -import zipkin2.reporter.Reporter; -import zipkin2.reporter.Sender; -import zipkin2.reporter.brave.ZipkinSpanHandler; -import zipkin2.reporter.urlconnection.URLConnectionSender; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.client.RestTemplate; - -/** - * Configurations for Zipkin. Those are imported by {@link ZipkinAutoConfiguration}. - * - * @author Moritz Halbritter - */ -class ZipkinConfigurations { - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties(ZipkinProperties.class) - static class SenderConfiguration { - - @Bean - @ConditionalOnMissingBean - @ConditionalOnClass(URLConnectionSender.class) - Sender urlConnectionSender(ZipkinProperties properties) { - return URLConnectionSender.newBuilder().connectTimeout((int) properties.getConnectTimeout().getSeconds()) - .readTimeout((int) properties.getReadTimeout().getSeconds()).endpoint(properties.getEndpoint()) - .build(); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnBean(RestTemplateBuilder.class) - @ConditionalOnMissingClass("zipkin2.reporter.urlconnection.URLConnectionSender") - Sender restTemplateSender(ZipkinProperties properties, RestTemplateBuilder restTemplateBuilder) { - RestTemplate restTemplate = restTemplateBuilder.setConnectTimeout(properties.getConnectTimeout()) - .setReadTimeout(properties.getReadTimeout()).build(); - return new ZipkinRestTemplateSender(properties.getEndpoint(), restTemplate); - } - - } - - @Configuration(proxyBeanMethods = false) - static class ReporterConfiguration { - - @Bean - @ConditionalOnMissingBean - @ConditionalOnBean(Sender.class) - Reporter spanReporter(Sender sender, BytesEncoder encoder) { - return AsyncReporter.builder(sender).build(encoder); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(ZipkinSpanHandler.class) - static class BraveConfiguration { - - @Bean - @ConditionalOnMissingBean - @ConditionalOnBean(Reporter.class) - SpanHandler zipkinSpanHandler(Reporter spanReporter) { - return ZipkinSpanHandler.newBuilder(spanReporter).build(); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(ZipkinSpanExporter.class) - static class OpenTelemetryConfiguration { - - @Bean - @ConditionalOnMissingBean - @ConditionalOnBean(Sender.class) - ZipkinSpanExporter zipkinSpanExporter(BytesEncoder encoder, Sender sender) { - return ZipkinSpanExporter.builder().setEncoder(encoder).setSender(sender).build(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinProperties.java deleted file mode 100644 index 088ae8ee42b1..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinProperties.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; - -import java.time.Duration; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * Configuration properties for {@link ZipkinAutoConfiguration}. - * - * @author Moritz Halbritter - * @since 3.0.0 - */ -@ConfigurationProperties("management.zipkin.tracing") -public class ZipkinProperties { - - /** - * URL to the Zipkin API. - */ - private String endpoint = "http://localhost:9411/api/v2/spans"; - - /** - * Connection timeout for requests to Zipkin. - */ - private Duration connectTimeout = Duration.ofSeconds(1); - - /** - * Read timeout for requests to Zipkin. - */ - private Duration readTimeout = Duration.ofSeconds(10); - - public String getEndpoint() { - return this.endpoint; - } - - public void setEndpoint(String endpoint) { - this.endpoint = endpoint; - } - - public Duration getConnectTimeout() { - return this.connectTimeout; - } - - public void setConnectTimeout(Duration connectTimeout) { - this.connectTimeout = connectTimeout; - } - - public Duration getReadTimeout() { - return this.readTimeout; - } - - public void setReadTimeout(Duration readTimeout) { - this.readTimeout = readTimeout; - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSender.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSender.java deleted file mode 100644 index c3fea73f761f..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSender.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.List; -import java.util.zip.GZIPOutputStream; - -import zipkin2.Call; -import zipkin2.Callback; -import zipkin2.CheckResult; -import zipkin2.codec.Encoding; -import zipkin2.reporter.BytesMessageEncoder; -import zipkin2.reporter.ClosedSenderException; -import zipkin2.reporter.Sender; - -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.util.unit.DataSize; -import org.springframework.web.client.RestTemplate; - -/** - * A Zipkin {@link Sender} which uses {@link RestTemplate} for HTTP communication. - * Supports automatic compression with gzip. - * - * @author Moritz Halbritter - */ -class ZipkinRestTemplateSender extends Sender { - - private static final DataSize MESSAGE_MAX_BYTES = DataSize.ofKilobytes(512); - - private final String endpoint; - - private final RestTemplate restTemplate; - - private volatile boolean closed; - - ZipkinRestTemplateSender(String endpoint, RestTemplate restTemplate) { - this.endpoint = endpoint; - this.restTemplate = restTemplate; - } - - @Override - public Encoding encoding() { - return Encoding.JSON; - } - - @Override - public int messageMaxBytes() { - return (int) MESSAGE_MAX_BYTES.toBytes(); - } - - @Override - public int messageSizeInBytes(List encodedSpans) { - return encoding().listSizeInBytes(encodedSpans); - } - - @Override - public int messageSizeInBytes(int encodedSizeInBytes) { - return encoding().listSizeInBytes(encodedSizeInBytes); - } - - @Override - public Call sendSpans(List encodedSpans) { - if (this.closed) { - throw new ClosedSenderException(); - } - return new HttpCall(this.endpoint, BytesMessageEncoder.JSON.encode(encodedSpans), this.restTemplate); - } - - @Override - public CheckResult check() { - try { - sendSpans(List.of()).execute(); - return CheckResult.OK; - } - catch (IOException | RuntimeException ex) { - return CheckResult.failed(ex); - } - } - - @Override - public void close() throws IOException { - this.closed = true; - } - - private static class HttpCall extends Call.Base { - - /** - * Only use gzip compression on data which is bigger than this in bytes. - */ - private static final DataSize COMPRESSION_THRESHOLD = DataSize.ofKilobytes(1); - - private final String endpoint; - - private final byte[] body; - - private final RestTemplate restTemplate; - - HttpCall(String endpoint, byte[] body, RestTemplate restTemplate) { - this.endpoint = endpoint; - this.body = body; - this.restTemplate = restTemplate; - } - - @Override - protected Void doExecute() throws IOException { - HttpHeaders headers = new HttpHeaders(); - headers.set("b3", "0"); - headers.set("Content-Type", "application/json"); - byte[] body; - if (needsCompression(this.body)) { - headers.set("Content-Encoding", "gzip"); - body = compress(this.body); - } - else { - body = this.body; - } - HttpEntity request = new HttpEntity<>(body, headers); - this.restTemplate.exchange(this.endpoint, HttpMethod.POST, request, Void.class); - return null; - } - - private boolean needsCompression(byte[] body) { - return body.length > COMPRESSION_THRESHOLD.toBytes(); - } - - @Override - protected void doEnqueue(Callback callback) { - try { - doExecute(); - callback.onSuccess(null); - } - catch (IOException | RuntimeException ex) { - callback.onError(ex); - } - } - - @Override - public Call clone() { - return new HttpCall(this.endpoint, this.body, this.restTemplate); - } - - private byte[] compress(byte[] input) throws IOException { - ByteArrayOutputStream result = new ByteArrayOutputStream(); - try (GZIPOutputStream gzip = new GZIPOutputStream(result)) { - gzip.write(input); - } - return result.toByteArray(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/package-info.java deleted file mode 100644 index 10dc7a7e8663..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-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. - */ - -/** - * Auto-configuration for tracing with Zipkin. - */ -package org.springframework.boot.actuate.autoconfigure.tracing.zipkin; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfiguration.java deleted file mode 100644 index e6e044f71fc5..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfiguration.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.wavefront; - -import java.time.Duration; - -import com.wavefront.sdk.common.WavefrontSender; -import com.wavefront.sdk.common.clients.WavefrontClient.Builder; - -import org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront.WavefrontMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.wavefront.WavefrontTracingAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.context.annotation.Bean; -import org.springframework.util.unit.DataSize; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for Wavefront common infrastructure. - * Metrics are auto-configured in {@link WavefrontMetricsExportAutoConfiguration}, tracing - * is auto-configured in {@link WavefrontTracingAutoConfiguration}. - * - * @author Moritz Halbritter - * @since 3.0.0 - */ -@AutoConfiguration -@ConditionalOnClass(WavefrontSender.class) -@EnableConfigurationProperties(WavefrontProperties.class) -public class WavefrontAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - public WavefrontSender wavefrontSender(WavefrontProperties properties) { - Builder builder = new Builder(properties.getEffectiveUri().toString(), properties.getApiTokenOrThrow()); - PropertyMapper mapper = PropertyMapper.get().alwaysApplyingWhenNonNull(); - WavefrontProperties.Sender sender = properties.getSender(); - mapper.from(sender.getMaxQueueSize()).to(builder::maxQueueSize); - mapper.from(sender.getFlushInterval()).asInt(Duration::getSeconds).to(builder::flushIntervalSeconds); - mapper.from(sender.getMessageSize()).asInt(DataSize::toBytes).to(builder::messageSizeBytes); - mapper.from(sender.getBatchSize()).to(builder::batchSize); - return builder.build(); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontProperties.java deleted file mode 100644 index 33576b4af9ea..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontProperties.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.wavefront; - -import java.net.InetAddress; -import java.net.URI; -import java.net.UnknownHostException; -import java.time.Duration; - -import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PushRegistryProperties; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException; -import org.springframework.util.unit.DataSize; - -/** - * Configuration properties to configure Wavefront. - * - * @author Moritz Halbritter - * @since 3.0.0 - */ -@ConfigurationProperties(prefix = "management.wavefront") -public class WavefrontProperties { - - /** - * URI to ship metrics and traces to. - */ - private URI uri = URI.create("https://longboard.wavefront.com"); - - /** - * Unique identifier for the app instance that is the source of metrics being - * published to Wavefront. Defaults to the local host name. - */ - private String source; - - /** - * API token used when publishing metrics directly to the Wavefront API host. - */ - private String apiToken; - - /** - * Sender configuration. - */ - private final Sender sender = new Sender(); - - /** - * Metrics configuration. - */ - private final Metrics metrics = new Metrics(); - - /** - * Tracing configuration. - */ - private final Tracing tracing = new Tracing(); - - public Sender getSender() { - return this.sender; - } - - public Metrics getMetrics() { - return this.metrics; - } - - public Tracing getTracing() { - return this.tracing; - } - - public URI getUri() { - return this.uri; - } - - public void setUri(URI uri) { - this.uri = uri; - } - - public String getSource() { - return this.source; - } - - public void setSource(String source) { - this.source = source; - } - - public String getApiToken() { - return this.apiToken; - } - - public void setApiToken(String apiToken) { - this.apiToken = apiToken; - } - - /** - * Returns the effective URI of the wavefront instance. This will not be the same URI - * given through {@link #setUri(URI)} when a proxy is used. - * @return the effective URI of the wavefront instance - */ - public URI getEffectiveUri() { - if (usesProxy()) { - // See io.micrometer.wavefront.WavefrontMeterRegistry.getWavefrontReportingUri - return URI.create(this.uri.toString().replace("proxy://", "http://")); - } - return this.uri; - } - - /** - * Returns the API token or throws an exception if the API token is mandatory. If a - * proxy is used, the API token is optional. - * @return the API token - */ - public String getApiTokenOrThrow() { - if (this.apiToken == null && !usesProxy()) { - throw new InvalidConfigurationPropertyValueException("management.wavefront.api-token", null, - "This property is mandatory whenever publishing directly to the Wavefront API"); - } - return this.apiToken; - } - - public String getSourceOrDefault() { - if (this.source != null) { - return this.source; - } - return getSourceDefault(); - } - - private String getSourceDefault() { - try { - return InetAddress.getLocalHost().getHostName(); - } - catch (UnknownHostException ex) { - return "unknown"; - } - } - - private boolean usesProxy() { - return "proxy".equals(this.uri.getScheme()); - } - - public static class Sender { - - /** - * Maximum size of queued messages. - */ - private int maxQueueSize = 50000; - - /** - * Flush interval to send queued messages. - */ - private Duration flushInterval = Duration.ofSeconds(1); - - /** - * Maximum size of a message. - */ - private DataSize messageSize = DataSize.ofBytes(Integer.MAX_VALUE); - - /** - * Number of measurements per request to use for Wavefront. If more measurements - * are found, then multiple requests will be made. - */ - private int batchSize = 10000; - - public int getMaxQueueSize() { - return this.maxQueueSize; - } - - public void setMaxQueueSize(int maxQueueSize) { - this.maxQueueSize = maxQueueSize; - } - - public Duration getFlushInterval() { - return this.flushInterval; - } - - public void setFlushInterval(Duration flushInterval) { - this.flushInterval = flushInterval; - } - - public DataSize getMessageSize() { - return this.messageSize; - } - - public void setMessageSize(DataSize messageSize) { - this.messageSize = messageSize; - } - - public int getBatchSize() { - return this.batchSize; - } - - public void setBatchSize(int batchSize) { - this.batchSize = batchSize; - } - - } - - public static class Metrics { - - /** - * Export configuration. - */ - private Export export = new Export(); - - public Export getExport() { - return this.export; - } - - public void setExport(Export export) { - this.export = export; - } - - public static class Export extends PushRegistryProperties { - - /** - * Global prefix to separate metrics originating from this app's - * instrumentation from those originating from other Wavefront integrations - * when viewed in the Wavefront UI. - */ - private String globalPrefix; - - public String getGlobalPrefix() { - return this.globalPrefix; - } - - public void setGlobalPrefix(String globalPrefix) { - this.globalPrefix = globalPrefix; - } - - /** - * See {@link PushRegistryProperties#getBatchSize()}. - */ - @Override - public Integer getBatchSize() { - throw new UnsupportedOperationException("Use Sender.getBatchSize() instead"); - } - - /** - * See {@link PushRegistryProperties#setBatchSize(Integer)}. - */ - @Override - public void setBatchSize(Integer batchSize) { - throw new UnsupportedOperationException("Use Sender.setBatchSize(int) instead"); - } - - } - - } - - public static class Tracing { - - /** - * Application name. Defaults to 'spring.application.name'. - */ - private String applicationName; - - /** - * Service name. Defaults to 'spring.application.name'. - */ - private String serviceName; - - public String getServiceName() { - return this.serviceName; - } - - public void setServiceName(String serviceName) { - this.serviceName = serviceName; - } - - public String getApplicationName() { - return this.applicationName; - } - - public void setApplicationName(String applicationName) { - this.applicationName = applicationName; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/package-info.java deleted file mode 100644 index 213eb6cccf64..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-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. - */ - -/** - * Classes shared between Wavefront tracing and metrics. - */ -package org.springframework.boot.actuate.autoconfigure.wavefront; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/LocalManagementPort.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/LocalManagementPort.java index e4404b9d9976..01e5213e1019 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/LocalManagementPort.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/LocalManagementPort.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -28,8 +28,7 @@ * Annotation at the field or method/constructor parameter level that injects the HTTP * management port that got allocated at runtime. Provides a convenient alternative for * @Value("${local.management.port}"). - * @deprecated since 2.7.0 for removal in 2.9.0 in favor of - * {@code org.springframework.boot.test.web.server.LocalManagementPort} + * * @author Stephane Nicoll * @since 2.0.0 */ @@ -37,7 +36,6 @@ @Retention(RetentionPolicy.RUNTIME) @Documented @Value("${local.management.port}") -@Deprecated public @interface LocalManagementPort { } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 316290f82b82..a27a8a6940ff 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -54,12 +54,6 @@ "sun.java.command" ] }, - { - "name": "management.endpoint.health.probes.add-additional-paths", - "type": "java.lang.Boolean", - "description": "Whether to make the liveness and readiness health groups available on the main server port.", - "defaultValue": false - }, { "name": "management.endpoint.health.probes.enabled", "type": "java.lang.Boolean", @@ -1832,7 +1826,7 @@ "type": "java.lang.String", "deprecation": { "level": "error", - "replacement": "management.wavefront.api-token" + "replacement": "management.wavefront.metrics.export.api-token" } }, { @@ -1840,7 +1834,7 @@ "type": "java.lang.Integer", "deprecation": { "level": "error", - "replacement": "management.wavefront.sender.batch-size" + "replacement": "management.wavefront.metrics.export.batch-size" } }, { @@ -1885,7 +1879,7 @@ "type": "java.time.Duration", "deprecation": { "level": "error", - "replacement": "management.wavefront.sender.flush-interval" + "replacement": "management.wavefront.metrics.export.sender.flush-interval" } }, { @@ -1893,7 +1887,7 @@ "type": "java.lang.Integer", "deprecation": { "level": "error", - "replacement": "management.wavefront.sender.max-queue-size" + "replacement": "management.wavefront.metrics.export.sender.max-queue-size" } }, { @@ -1901,7 +1895,7 @@ "type": "org.springframework.util.unit.DataSize", "deprecation": { "level": "error", - "replacement": "management.wavefront.sender.message-size" + "replacement": "management.wavefront.metrics.export.sender.message-size" } }, { @@ -1909,7 +1903,7 @@ "type": "java.lang.String", "deprecation": { "level": "error", - "replacement": "management.wavefront.source" + "replacement": "management.wavefront.metrics.export.source" } }, { @@ -1925,7 +1919,7 @@ "type": "java.net.URI", "deprecation": { "level": "error", - "replacement": "management.wavefront.uri" + "replacement": "management.wavefront.metrics.export.uri" } }, { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index cb999708e2c5..0ba704f63db8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -95,12 +95,6 @@ org.springframework.boot.actuate.autoconfigure.startup.StartupEndpointAutoConfig org.springframework.boot.actuate.autoconfigure.system.DiskSpaceHealthContributorAutoConfiguration org.springframework.boot.actuate.autoconfigure.trace.http.HttpTraceAutoConfiguration org.springframework.boot.actuate.autoconfigure.trace.http.HttpTraceEndpointAutoConfiguration -org.springframework.boot.actuate.autoconfigure.tracing.BraveAutoConfiguration -org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingAutoConfiguration -org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryAutoConfiguration -org.springframework.boot.actuate.autoconfigure.tracing.wavefront.WavefrontTracingAutoConfiguration -org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinAutoConfiguration -org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontAutoConfiguration org.springframework.boot.actuate.autoconfigure.web.mappings.MappingsEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementContextAutoConfiguration org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java index 9996e2debea0..fb5ec4725693 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -20,8 +20,6 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration; @@ -71,11 +69,10 @@ void testChild() { @Configuration @EnableAutoConfiguration(exclude = { ElasticsearchDataAutoConfiguration.class, ElasticsearchRepositoriesAutoConfiguration.class, CassandraAutoConfiguration.class, - CassandraDataAutoConfiguration.class, MicrometerTracingAutoConfiguration.class, - MongoDataAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class, Neo4jAutoConfiguration.class, - Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class, RedisAutoConfiguration.class, - RedisRepositoriesAutoConfiguration.class, FlywayAutoConfiguration.class, MetricsAutoConfiguration.class, - WavefrontAutoConfiguration.class }) + CassandraDataAutoConfiguration.class, MongoDataAutoConfiguration.class, + MongoReactiveDataAutoConfiguration.class, Neo4jAutoConfiguration.class, Neo4jDataAutoConfiguration.class, + Neo4jRepositoriesAutoConfiguration.class, RedisAutoConfiguration.class, + RedisRepositoriesAutoConfiguration.class, FlywayAutoConfiguration.class, MetricsAutoConfiguration.class }) static class Parent { } @@ -83,11 +80,10 @@ static class Parent { @Configuration @EnableAutoConfiguration(exclude = { ElasticsearchDataAutoConfiguration.class, ElasticsearchRepositoriesAutoConfiguration.class, CassandraAutoConfiguration.class, - CassandraDataAutoConfiguration.class, MicrometerTracingAutoConfiguration.class, - MongoDataAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class, Neo4jAutoConfiguration.class, - Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class, RedisAutoConfiguration.class, - RedisRepositoriesAutoConfiguration.class, FlywayAutoConfiguration.class, MetricsAutoConfiguration.class, - WavefrontAutoConfiguration.class }) + CassandraDataAutoConfiguration.class, MongoDataAutoConfiguration.class, + MongoReactiveDataAutoConfiguration.class, Neo4jAutoConfiguration.class, Neo4jDataAutoConfiguration.class, + Neo4jRepositoriesAutoConfiguration.class, RedisAutoConfiguration.class, + RedisRepositoriesAutoConfiguration.class, FlywayAutoConfiguration.class, MetricsAutoConfiguration.class }) static class Child { } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfigurationTests.java deleted file mode 100644 index 5c1f4d9aa4c3..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfigurationTests.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.elasticsearch; - -import org.elasticsearch.client.RestClient; -import org.elasticsearch.client.RestClientBuilder; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestClientHealthIndicator; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ElasticSearchRestHealthContributorAutoConfiguration}. - * - * @author Filip Hrisafov - * @author Andy Wilkinson - */ -class ElasticSearchRestHealthContributorAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(ElasticsearchRestClientAutoConfiguration.class, - ElasticSearchRestHealthContributorAutoConfiguration.class, - HealthContributorAutoConfiguration.class)); - - @Test - void runShouldCreateIndicator() { - this.contextRunner.run((context) -> assertThat(context) - .hasSingleBean(ElasticsearchRestClientHealthIndicator.class).hasBean("elasticsearchHealthContributor")); - } - - @Test - @SuppressWarnings("deprecation") - void runWithoutRestHighLevelClientAndWithoutRestClientShouldNotCreateIndicator() { - this.contextRunner - .withClassLoader( - new FilteredClassLoader(org.elasticsearch.client.RestHighLevelClient.class, RestClient.class)) - .run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestClientHealthIndicator.class) - .doesNotHaveBean("elasticsearchHealthContributor")); - } - - @Test - void runWithoutRestHighLevelClientAndWithRestClientShouldCreateIndicator() { - this.contextRunner.withUserConfiguration(CustomRestClientConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestClientHealthIndicator.class) - .hasBean("elasticsearchHealthContributor")); - } - - @Test - void runWithRestHighLevelClientAndWithRestClientShouldCreateIndicator() { - this.contextRunner.withUserConfiguration(CustomRestHighClientConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestClientHealthIndicator.class) - .hasBean("elasticsearchHealthContributor")); - } - - @Test - void runWhenDisabledShouldNotCreateIndicator() { - this.contextRunner.withPropertyValues("management.health.elasticsearch.enabled:false") - .run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestClientHealthIndicator.class) - .doesNotHaveBean("elasticsearchHealthContributor")); - } - - @Configuration(proxyBeanMethods = false) - static class CustomRestClientConfiguration { - - @Bean - RestClient customRestClient(RestClientBuilder builder) { - return builder.build(); - } - - } - - @Configuration(proxyBeanMethods = false) - @SuppressWarnings("deprecation") - static class CustomRestHighClientConfiguration { - - @Bean - org.elasticsearch.client.RestHighLevelClient customRestHighClient(RestClientBuilder builder) { - return new org.elasticsearch.client.RestHighLevelClient(builder); - } - - @Bean - RestClient customClient(org.elasticsearch.client.RestHighLevelClient restHighLevelClient) { - return restHighLevelClient.getLowLevelClient(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchReactiveHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchReactiveHealthContributorAutoConfigurationTests.java index 7cf3bce2fc27..c14fc96e4f62 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchReactiveHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchReactiveHealthContributorAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2020 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. @@ -20,7 +20,7 @@ import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; import org.springframework.boot.actuate.elasticsearch.ElasticsearchReactiveHealthIndicator; -import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestClientHealthIndicator; +import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration; import org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration; @@ -55,7 +55,7 @@ void runWithRegularIndicatorShouldOnlyCreateReactiveIndicator() { .withConfiguration(AutoConfigurations.of(ElasticSearchRestHealthContributorAutoConfiguration.class)) .run((context) -> assertThat(context).hasSingleBean(ElasticsearchReactiveHealthIndicator.class) .hasBean("elasticsearchHealthContributor") - .doesNotHaveBean(ElasticsearchRestClientHealthIndicator.class)); + .doesNotHaveBean(ElasticsearchRestHealthIndicator.class)); } @Test diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MappingsEndpointReactiveDocumentationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MappingsEndpointReactiveDocumentationTests.java index 6ecd2863f771..7ae63277f911 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MappingsEndpointReactiveDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MappingsEndpointReactiveDocumentationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -31,8 +31,8 @@ import org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MappingsEndpointServletDocumentationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MappingsEndpointServletDocumentationTests.java index b45f0ea735ee..4055c9752ce8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MappingsEndpointServletDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MappingsEndpointServletDocumentationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -33,8 +33,8 @@ import org.springframework.boot.actuate.web.mappings.servlet.ServletsMappingDescriptionProvider; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MetricsEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MetricsEndpointDocumentationTests.java index 6a179c35352f..e46f761b8b95 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MetricsEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/MetricsEndpointDocumentationTests.java @@ -16,8 +16,8 @@ package org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation; +import io.micrometer.binder.jvm.JvmMemoryMetrics; import io.micrometer.core.instrument.Statistic; -import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/PrometheusScrapeEndpointDocumentationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/PrometheusScrapeEndpointDocumentationTests.java index 128ff6033f17..a2df3d4446f6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/PrometheusScrapeEndpointDocumentationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/PrometheusScrapeEndpointDocumentationTests.java @@ -16,8 +16,8 @@ package org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation; +import io.micrometer.binder.jvm.JvmMemoryMetrics; import io.micrometer.core.instrument.Clock; -import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; import io.micrometer.prometheus.PrometheusMeterRegistry; import io.prometheus.client.CollectorRegistry; import io.prometheus.client.exporter.common.TextFormat; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java index c945ccc5769d..c25193341f45 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -20,9 +20,6 @@ import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.BraveAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontAutoConfiguration; import org.springframework.boot.actuate.health.HealthEndpointWebExtension; import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -83,8 +80,7 @@ private ReactiveWebApplicationContextRunner reactiveWebRunner() { MongoReactiveAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class, RepositoryRestMvcAutoConfiguration.class, HazelcastAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class, SolrAutoConfiguration.class, RedisAutoConfiguration.class, - RedisRepositoriesAutoConfiguration.class, MetricsAutoConfiguration.class, WavefrontAutoConfiguration.class, - BraveAutoConfiguration.class, OpenTelemetryAutoConfiguration.class }) + RedisRepositoriesAutoConfiguration.class, MetricsAutoConfiguration.class }) @SpringBootConfiguration static class WebEndpointTestApplication { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfigurationTests.java index ecb3a5ad2ad5..117819206805 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/JvmMetricsAutoConfigurationTests.java @@ -16,11 +16,11 @@ package org.springframework.boot.actuate.autoconfigure.metrics; -import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics; -import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics; -import io.micrometer.core.instrument.binder.jvm.JvmHeapPressureMetrics; -import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; -import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics; +import io.micrometer.binder.jvm.ClassLoaderMetrics; +import io.micrometer.binder.jvm.JvmGcMetrics; +import io.micrometer.binder.jvm.JvmHeapPressureMetrics; +import io.micrometer.binder.jvm.JvmMemoryMetrics; +import io.micrometer.binder.jvm.JvmThreadMetrics; import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests.java index 2e9a10bdb743..3e79aa996a9b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithLog4jLoggerContextAutoConfigurationTests.java @@ -16,7 +16,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics; -import io.micrometer.core.instrument.binder.logging.Log4j2Metrics; +import io.micrometer.binder.logging.Log4j2Metrics; import org.apache.logging.log4j.LogManager; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java index 102618665834..87c99a8191a5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/Log4J2MetricsWithSlf4jLoggerContextAutoConfigurationTests.java @@ -16,7 +16,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics; -import io.micrometer.core.instrument.binder.logging.Log4j2Metrics; +import io.micrometer.binder.logging.Log4j2Metrics; import org.apache.logging.log4j.LogManager; import org.apache.logging.slf4j.SLF4JLoggerContext; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfigurationTests.java index b8c38301834a..86fa5d08519e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/LogbackMetricsAutoConfigurationTests.java @@ -16,7 +16,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics; -import io.micrometer.core.instrument.binder.logging.LogbackMetrics; +import io.micrometer.binder.logging.LogbackMetrics; import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationWithLog4j2AndLogbackTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationWithLog4j2AndLogbackTests.java index 7570c896c915..4790f8c00e91 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationWithLog4j2AndLogbackTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationWithLog4j2AndLogbackTests.java @@ -16,7 +16,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics; -import io.micrometer.core.instrument.binder.logging.LogbackMetrics; +import io.micrometer.binder.logging.LogbackMetrics; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfigurationTests.java index cba6e2c35545..8b643e49731a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/SystemMetricsAutoConfigurationTests.java @@ -20,10 +20,10 @@ import java.util.Arrays; import java.util.Collections; +import io.micrometer.binder.system.FileDescriptorMetrics; +import io.micrometer.binder.system.ProcessorMetrics; +import io.micrometer.binder.system.UptimeMetrics; import io.micrometer.core.instrument.Tags; -import io.micrometer.core.instrument.binder.system.FileDescriptorMetrics; -import io.micrometer.core.instrument.binder.system.ProcessorMetrics; -import io.micrometer.core.instrument.binder.system.UptimeMetrics; import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsAutoConfigurationTests.java index 5c16b62c6932..556b53128950 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/cache/CacheMetricsAutoConfigurationTests.java @@ -44,8 +44,8 @@ void autoConfiguredCache2kIsInstrumented() { this.contextRunner.withPropertyValues("spring.cache.type=cache2k", "spring.cache.cache-names=cache1,cache2") .run((context) -> { MeterRegistry registry = context.getBean(MeterRegistry.class); - registry.get("cache.gets").tags("name", "cache1").tags("cache.manager", "cacheManager").meter(); - registry.get("cache.gets").tags("name", "cache2").tags("cache.manager", "cacheManager").meter(); + registry.get("cache.gets").tags("name", "cache1").tags("cacheManager", "cacheManager").meter(); + registry.get("cache.gets").tags("name", "cache2").tags("cacheManager", "cacheManager").meter(); }); } @@ -54,8 +54,8 @@ void autoConfiguredCacheManagerIsInstrumented() { this.contextRunner.withPropertyValues("spring.cache.type=caffeine", "spring.cache.cache-names=cache1,cache2") .run((context) -> { MeterRegistry registry = context.getBean(MeterRegistry.class); - registry.get("cache.gets").tags("name", "cache1").tags("cache.manager", "cacheManager").meter(); - registry.get("cache.gets").tags("name", "cache2").tags("cache.manager", "cacheManager").meter(); + registry.get("cache.gets").tags("name", "cache1").tags("cacheManager", "cacheManager").meter(); + registry.get("cache.gets").tags("name", "cache2").tags("cacheManager", "cacheManager").meter(); }); } @@ -64,9 +64,9 @@ void autoConfiguredNonSupportedCacheManagerIsIgnored() { this.contextRunner.withPropertyValues("spring.cache.type=simple", "spring.cache.cache-names=cache1,cache2") .run((context) -> { MeterRegistry registry = context.getBean(MeterRegistry.class); - assertThat(registry.find("cache.gets").tags("name", "cache1").tags("cache.manager", "cacheManager") + assertThat(registry.find("cache.gets").tags("name", "cache1").tags("cacheManager", "cacheManager") .meter()).isNull(); - assertThat(registry.find("cache.gets").tags("name", "cache2").tags("cache.manager", "cacheManager") + assertThat(registry.find("cache.gets").tags("name", "cache2").tags("cacheManager", "cacheManager") .meter()).isNull(); }); } @@ -77,7 +77,7 @@ void cacheInstrumentationCanBeDisabled() { "spring.cache.cache-names=cache1").run((context) -> { MeterRegistry registry = context.getBean(MeterRegistry.class); assertThat(registry.find("cache.requests").tags("name", "cache1") - .tags("cache.manager", "cacheManager").meter()).isNull(); + .tags("cacheManager", "cacheManager").meter()).isNull(); }); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapterTests.java index 97117ce9adb5..003028375421 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/dynatrace/DynatracePropertiesConfigAdapterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -125,13 +125,6 @@ void whenPropertiesEnrichWithOneAgentMetadataIsSetAdapterEnrichWithOneAgentMetad assertThat(new DynatracePropertiesConfigAdapter(properties).enrichWithDynatraceMetadata()).isTrue(); } - @Test - void whenPropertiesUseDynatraceInstrumentsIsSetAdapterUseDynatraceInstrumentsReturnsIt() { - DynatraceProperties properties = new DynatraceProperties(); - properties.getV2().setUseDynatraceSummaryInstruments(false); - assertThat(new DynatracePropertiesConfigAdapter(properties).useDynatraceSummaryInstruments()).isFalse(); - } - @Test void whenPropertiesDefaultDimensionsIsSetAdapterDefaultDimensionsReturnsIt() { DynatraceProperties properties = new DynatraceProperties(); @@ -155,7 +148,6 @@ void defaultValues() { assertThat(properties.getV2().getMetricKeyPrefix()).isNull(); assertThat(properties.getV2().isEnrichWithDynatraceMetadata()).isTrue(); assertThat(properties.getV2().getDefaultDimensions()).isNull(); - assertThat(properties.getV2().isUseDynatraceSummaryInstruments()).isTrue(); assertThat(properties.getDeviceId()).isNull(); assertThat(properties.getTechnologyType()).isEqualTo("java"); assertThat(properties.getGroup()).isNull(); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioMetricsExportAutoConfigurationTests.java index d8af629c2b04..d96bcd3508d6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/humio/HumioMetricsExportAutoConfigurationTests.java @@ -16,8 +16,8 @@ package org.springframework.boot.actuate.autoconfigure.metrics.export.humio; +import io.micrometer.binder.jvm.JvmMemoryMetrics; import io.micrometer.core.instrument.Clock; -import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; import io.micrometer.humio.HumioConfig; import io.micrometer.humio.HumioMeterRegistry; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesConfigAdapterTests.java index 94c604a3f1d9..29b2a1ec5ca3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/properties/PushRegistryPropertiesConfigAdapterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2020 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. @@ -51,7 +51,7 @@ void whenPropertiesEnabledIsSetAdapterEnabledReturnsIt() { } @Test - protected void whenPropertiesBatchSizeIsSetAdapterBatchSizeReturnsIt() { + void whenPropertiesBatchSizeIsSetAdapterBatchSizeReturnsIt() { P properties = createProperties(); properties.setBatchSize(10042); assertThat(createConfigAdapter(properties).batchSize()).isEqualTo(10042); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfigurationTests.java index 0a300f5b42c8..f00a07d514dd 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfigurationTests.java @@ -16,12 +16,14 @@ package org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront; +import java.util.concurrent.LinkedBlockingQueue; + import com.wavefront.sdk.common.WavefrontSender; import io.micrometer.core.instrument.Clock; import io.micrometer.wavefront.WavefrontConfig; import io.micrometer.wavefront.WavefrontMeterRegistry; +import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -29,6 +31,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import static org.assertj.core.api.Assertions.as; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -48,22 +51,28 @@ void backsOffWithoutAClock() { this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(WavefrontMeterRegistry.class)); } + @Test + void failsWithoutAnApiTokenWhenPublishingDirectly() { + this.contextRunner.withUserConfiguration(BaseConfiguration.class) + .run((context) -> assertThat(context).hasFailed()); + } + @Test void autoConfigurationCanBeDisabledWithDefaultsEnabledProperty() { this.contextRunner.withUserConfiguration(BaseConfiguration.class) - .withPropertyValues("management.wavefront.api-token=abcde", + .withPropertyValues("management.wavefront.metrics.export.api-token=abcde", "management.defaults.metrics.export.enabled=false") .run((context) -> assertThat(context).doesNotHaveBean(WavefrontMeterRegistry.class) - .doesNotHaveBean(WavefrontConfig.class)); + .doesNotHaveBean(WavefrontConfig.class).doesNotHaveBean(WavefrontSender.class)); } @Test void autoConfigurationCanBeDisabledWithSpecificEnabledProperty() { this.contextRunner.withUserConfiguration(BaseConfiguration.class) - .withPropertyValues("management.wavefront.api-token=abcde", + .withPropertyValues("management.wavefront.metrics.export.api-token=abcde", "management.wavefront.metrics.export.enabled=false") .run((context) -> assertThat(context).doesNotHaveBean(WavefrontMeterRegistry.class) - .doesNotHaveBean(WavefrontConfig.class)); + .doesNotHaveBean(WavefrontConfig.class).doesNotHaveBean(WavefrontSender.class)); } @Test @@ -74,10 +83,51 @@ void allowsConfigToBeCustomized() { .hasSingleBean(WavefrontSender.class).hasBean("customConfig")); } + @Test + void defaultWavefrontSenderSettingsAreConsistent() { + this.contextRunner.withUserConfiguration(BaseConfiguration.class) + .withPropertyValues("management.wavefront.metrics.export.api-token=abcde").run((context) -> { + WavefrontProperties properties = new WavefrontProperties(); + WavefrontSender sender = context.getBean(WavefrontSender.class); + assertThat(sender) + .extracting("metricsBuffer", as(InstanceOfAssertFactories.type(LinkedBlockingQueue.class))) + .satisfies((queue) -> assertThat(queue.remainingCapacity() + queue.size()) + .isEqualTo(properties.getSender().getMaxQueueSize())); + assertThat(sender).hasFieldOrPropertyWithValue("batchSize", properties.getBatchSize()); + assertThat(sender).hasFieldOrPropertyWithValue("messageSizeBytes", + (int) properties.getSender().getMessageSize().toBytes()); + }); + } + + @Test + void configureWavefrontSender() { + this.contextRunner.withUserConfiguration(BaseConfiguration.class) + .withPropertyValues("management.wavefront.metrics.export.api-token=abcde", + "management.wavefront.metrics.export.batch-size=50", + "management.wavefront.metrics.export.sender.max-queue-size=100", + "management.wavefront.metrics.export.sender.message-size=1KB") + .run((context) -> { + WavefrontSender sender = context.getBean(WavefrontSender.class); + assertThat(sender).hasFieldOrPropertyWithValue("batchSize", 50); + assertThat(sender) + .extracting("metricsBuffer", as(InstanceOfAssertFactories.type(LinkedBlockingQueue.class))) + .satisfies((queue) -> assertThat(queue.remainingCapacity() + queue.size()).isEqualTo(100)); + assertThat(sender).hasFieldOrPropertyWithValue("messageSizeBytes", 1024); + }); + } + + @Test + void allowsWavefrontSenderToBeCustomized() { + this.contextRunner.withUserConfiguration(CustomSenderConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(Clock.class) + .hasSingleBean(WavefrontMeterRegistry.class).hasSingleBean(WavefrontConfig.class) + .hasSingleBean(WavefrontSender.class).hasBean("customSender")); + } + @Test void allowsRegistryToBeCustomized() { this.contextRunner.withUserConfiguration(CustomRegistryConfiguration.class) - .withPropertyValues("management.wavefront.api-token=abcde") + .withPropertyValues("management.wavefront.metrics.export.api-token=abcde") .run((context) -> assertThat(context).hasSingleBean(Clock.class).hasSingleBean(WavefrontConfig.class) .hasSingleBean(WavefrontMeterRegistry.class).hasBean("customRegistry")); } @@ -85,7 +135,7 @@ void allowsRegistryToBeCustomized() { @Test void stopsMeterRegistryWhenContextIsClosed() { this.contextRunner.withUserConfiguration(BaseConfiguration.class) - .withPropertyValues("management.wavefront.api-token=abcde").run((context) -> { + .withPropertyValues("management.wavefront.metrics.export.api-token=abcde").run((context) -> { WavefrontMeterRegistry registry = context.getBean(WavefrontMeterRegistry.class); assertThat(registry.isClosed()).isFalse(); context.close(); @@ -96,11 +146,6 @@ void stopsMeterRegistryWhenContextIsClosed() { @Configuration(proxyBeanMethods = false) static class BaseConfiguration { - @Bean - WavefrontSender customWavefrontSender() { - return Mockito.mock(WavefrontSender.class); - } - @Bean Clock clock() { return Clock.SYSTEM; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapterTests.java index 145765b78358..82a5b6d31d54 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesConfigAdapterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -16,11 +16,11 @@ package org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront; +import java.net.URI; + import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PushRegistryPropertiesConfigAdapterTests; -import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties; -import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties.Metrics.Export; import static org.assertj.core.api.Assertions.assertThat; @@ -28,35 +28,46 @@ * Tests for {@link WavefrontPropertiesConfigAdapter}. * * @author Stephane Nicoll - * @author Moritz Halbritter */ -class WavefrontPropertiesConfigAdapterTests extends - PushRegistryPropertiesConfigAdapterTests { +class WavefrontPropertiesConfigAdapterTests + extends PushRegistryPropertiesConfigAdapterTests { @Override - protected WavefrontProperties.Metrics.Export createProperties() { - return new WavefrontProperties.Metrics.Export(); + protected WavefrontProperties createProperties() { + return new WavefrontProperties(); } @Override - protected WavefrontPropertiesConfigAdapter createConfigAdapter(WavefrontProperties.Metrics.Export export) { - WavefrontProperties properties = new WavefrontProperties(); - properties.getMetrics().setExport(export); + protected WavefrontPropertiesConfigAdapter createConfigAdapter(WavefrontProperties properties) { return new WavefrontPropertiesConfigAdapter(properties); } + @Test + void whenPropertiesUriIsSetAdapterUriReturnsIt() { + WavefrontProperties properties = createProperties(); + properties.setUri(URI.create("https://wavefront.example.com")); + assertThat(createConfigAdapter(properties).uri()).isEqualTo("https://wavefront.example.com"); + } + + @Test + void whenPropertiesSourceIsSetAdapterSourceReturnsIt() { + WavefrontProperties properties = createProperties(); + properties.setSource("test"); + assertThat(createConfigAdapter(properties).source()).isEqualTo("test"); + } + + @Test + void whenPropertiesApiTokenIsSetAdapterApiTokenReturnsIt() { + WavefrontProperties properties = createProperties(); + properties.setApiToken("ABC123"); + assertThat(createConfigAdapter(properties).apiToken()).isEqualTo("ABC123"); + } + @Test void whenPropertiesGlobalPrefixIsSetAdapterGlobalPrefixReturnsIt() { - Export properties = createProperties(); + WavefrontProperties properties = createProperties(); properties.setGlobalPrefix("test"); assertThat(createConfigAdapter(properties).globalPrefix()).isEqualTo("test"); } - @Override - protected void whenPropertiesBatchSizeIsSetAdapterBatchSizeReturnsIt() { - WavefrontProperties properties = new WavefrontProperties(); - properties.getSender().setBatchSize(10042); - assertThat(createConfigAdapter(properties.getMetrics().getExport()).batchSize()).isEqualTo(10042); - } - } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontPropertiesMetricsExportTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesTests.java similarity index 58% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontPropertiesMetricsExportTests.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesTests.java index f467aa7c374a..4ec6050d468c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontPropertiesMetricsExportTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontPropertiesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2020 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. @@ -14,31 +14,29 @@ * limitations under the License. */ -package org.springframework.boot.actuate.autoconfigure.wavefront; +package org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront; import io.micrometer.wavefront.WavefrontConfig; import org.junit.jupiter.api.Test; +import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PushRegistryPropertiesTests; + import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link WavefrontProperties.Metrics.Export}. + * Tests for {@link WavefrontProperties}. * * @author Stephane Nicoll - * @author Moritz Halbritter */ -class WavefrontPropertiesMetricsExportTests { +class WavefrontPropertiesTests extends PushRegistryPropertiesTests { @Test - @SuppressWarnings("deprecation") void defaultValuesAreConsistent() { - WavefrontProperties.Metrics.Export properties = new WavefrontProperties.Metrics.Export(); + WavefrontProperties properties = new WavefrontProperties(); WavefrontConfig config = WavefrontConfig.DEFAULT_DIRECT; - assertThat(properties.getConnectTimeout()).isEqualTo(config.connectTimeout()); + assertStepRegistryDefaultValues(properties, config); + assertThat(properties.getUri().toString()).isEqualTo(config.uri()); assertThat(properties.getGlobalPrefix()).isEqualTo(config.globalPrefix()); - assertThat(properties.getReadTimeout()).isEqualTo(config.readTimeout()); - assertThat(properties.getStep()).isEqualTo(config.step()); - assertThat(properties.isEnabled()).isEqualTo(config.enabled()); } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java index 460232c3bb8a..77d37405d325 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -29,7 +29,6 @@ import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.boot.LazyInitializationBeanFactoryPostProcessor; import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; @@ -91,19 +90,6 @@ void allDataSourcesCanBeInstrumented() { }); } - @Test - void allDataSourcesCanBeInstrumentedWithLazyInitialization() { - this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)).withInitializer( - (context) -> context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor())) - .withUserConfiguration(TwoDataSourcesConfiguration.class).run((context) -> { - context.getBean("firstDataSource", DataSource.class).getConnection().getMetaData(); - context.getBean("secondOne", DataSource.class).getConnection().getMetaData(); - MeterRegistry registry = context.getBean(MeterRegistry.class); - registry.get("jdbc.connections.max").tags("name", "first").meter(); - registry.get("jdbc.connections.max").tags("name", "secondOne").meter(); - }); - } - @Test void autoConfiguredHikariDataSourceIsInstrumented() { this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) @@ -181,21 +167,6 @@ void someHikariDataSourcesCanBeInstrumented() { }); } - @Test - void allHikariDataSourcesCanBeInstrumentedWhenUsingLazyInitialization() { - this.contextRunner.withUserConfiguration(TwoHikariDataSourcesConfiguration.class) - .withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) - .withInitializer((context) -> context - .addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor())) - .run((context) -> { - context.getBean("firstDataSource", DataSource.class).getConnection(); - context.getBean("secondOne", DataSource.class).getConnection(); - MeterRegistry registry = context.getBean(MeterRegistry.class); - registry.get("hikaricp.connections").tags("pool", "firstDataSource").meter(); - registry.get("hikaricp.connections").tags("pool", "secondOne").meter(); - }); - } - @Test void hikariProxiedDataSourceCanBeInstrumented() { this.contextRunner.withUserConfiguration(ProxiedHikariDataSourcesConfiguration.class) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfigurationTests.java index 43d96561b7e3..cd323a72ba22 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/mongo/MongoMetricsAutoConfigurationTests.java @@ -23,12 +23,12 @@ import com.mongodb.client.internal.MongoClientImpl; import com.mongodb.connection.ConnectionPoolSettings; import com.mongodb.event.ConnectionPoolListener; -import io.micrometer.core.instrument.binder.mongodb.DefaultMongoCommandTagsProvider; -import io.micrometer.core.instrument.binder.mongodb.DefaultMongoConnectionPoolTagsProvider; -import io.micrometer.core.instrument.binder.mongodb.MongoCommandTagsProvider; -import io.micrometer.core.instrument.binder.mongodb.MongoConnectionPoolTagsProvider; -import io.micrometer.core.instrument.binder.mongodb.MongoMetricsCommandListener; -import io.micrometer.core.instrument.binder.mongodb.MongoMetricsConnectionPoolListener; +import io.micrometer.binder.mongodb.DefaultMongoCommandTagsProvider; +import io.micrometer.binder.mongodb.DefaultMongoConnectionPoolTagsProvider; +import io.micrometer.binder.mongodb.MongoCommandTagsProvider; +import io.micrometer.binder.mongodb.MongoConnectionPoolTagsProvider; +import io.micrometer.binder.mongodb.MongoMetricsCommandListener; +import io.micrometer.binder.mongodb.MongoMetricsConnectionPoolListener; import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsIntegrationTests.java index 697bb0e086a5..d4518ab9f60b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsIntegrationTests.java @@ -22,11 +22,11 @@ import java.util.Set; import java.util.concurrent.CyclicBarrier; +import io.micrometer.binder.jvm.JvmMemoryMetrics; +import io.micrometer.binder.logging.LogbackMetrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.MockClock; import io.micrometer.core.instrument.binder.MeterBinder; -import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; -import io.micrometer.core.instrument.binder.logging.LogbackMetrics; import io.micrometer.core.instrument.simple.SimpleConfig; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import jakarta.servlet.DispatcherType; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfigurationTests.java index 1356e9ab5ad9..617e5ccb9e4f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfigurationTests.java @@ -19,8 +19,8 @@ import java.util.Collections; import java.util.concurrent.atomic.AtomicInteger; +import io.micrometer.binder.tomcat.TomcatMetrics; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.binder.tomcat.TomcatMetrics; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.apache.tomcat.util.modeler.Registry; import org.junit.jupiter.api.Test; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfigurationTests.java index 3b59e4550e8f..fdd38c979636 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfigurationTests.java @@ -19,14 +19,14 @@ import java.util.ArrayList; import java.util.List; -import io.micrometer.common.KeyValue; -import io.micrometer.common.KeyValues; +import io.micrometer.common.Tag; +import io.micrometer.common.Tags; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.observation.MeterObservationHandler; import io.micrometer.core.instrument.search.MeterNotFoundException; import io.micrometer.observation.Observation; import io.micrometer.observation.Observation.Context; -import io.micrometer.observation.Observation.GlobalKeyValuesProvider; +import io.micrometer.observation.Observation.GlobalTagsProvider; import io.micrometer.observation.ObservationHandler; import io.micrometer.observation.ObservationHandler.AllMatchingCompositeObservationHandler; import io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObservationHandler; @@ -104,7 +104,7 @@ void autoConfiguresGlobalTagsProvider() { ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class); Context micrometerContext = new Context(); Observation.start("test-observation", micrometerContext, observationRegistry).stop(); - assertThat(micrometerContext.getAllKeyValues()).containsExactly(KeyValue.of("tag1", "value1")); + assertThat(micrometerContext.getAllTags()).containsExactly(Tag.of("tag1", "value1")); }); } @@ -164,16 +164,16 @@ ObservationPredicate customPredicate() { static class GlobalTagsProviders { @Bean - Observation.GlobalKeyValuesProvider customTagsProvider() { - return new GlobalKeyValuesProvider<>() { + GlobalTagsProvider customTagsProvider() { + return new GlobalTagsProvider<>() { @Override public boolean supportsContext(Context context) { return true; } @Override - public KeyValues getLowCardinalityKeyValues(Context context) { - return KeyValues.of("tag1", "value1"); + public Tags getLowCardinalityTags(Context context) { + return Tags.of("tag1", "value1"); } }; } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfigurationTests.java index 3c53693c0890..f3bac5eae322 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/ManagementWebSecurityAutoConfigurationTests.java @@ -136,10 +136,10 @@ void backOffIfOAuth2ResourceServerAutoConfigurationPresent() { void backOffIfSaml2RelyingPartyAutoConfigurationPresent() { this.contextRunner.withConfiguration(AutoConfigurations.of(Saml2RelyingPartyAutoConfiguration.class)) .withPropertyValues( - "spring.security.saml2.relyingparty.registration.simplesamlphp.asserting-party.single-sign-on.url=https://simplesaml-for-spring-saml/SSOService.php", - "spring.security.saml2.relyingparty.registration.simplesamlphp.asserting-party.single-sign-on.sign-request=false", - "spring.security.saml2.relyingparty.registration.simplesamlphp.asserting-party.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", - "spring.security.saml2.relyingparty.registration.simplesamlphp.asserting-party.verification.credentials[0].certificate-location=classpath:saml/certificate-location") + "spring.security.saml2.relyingparty.registration.simplesamlphp.identity-provider.single-sign-on.url=https://simplesaml-for-spring-saml/SSOService.php", + "spring.security.saml2.relyingparty.registration.simplesamlphp.identity-provider.single-sign-on.sign-request=false", + "spring.security.saml2.relyingparty.registration.simplesamlphp.identityprovider.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", + "spring.security.saml2.relyingparty.registration.simplesamlphp.identityprovider.verification.credentials[0].certificate-location=classpath:saml/certificate-location") .run((context) -> assertThat(context).doesNotHaveBean(ManagementWebSecurityAutoConfiguration.class) .doesNotHaveBean(MANAGEMENT_SECURITY_FILTER_CHAIN_BEAN)); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfigurationTests.java deleted file mode 100644 index e0cd2e147053..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfigurationTests.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing; - -import brave.Tracer; -import brave.Tracing; -import brave.propagation.CurrentTraceContext; -import brave.propagation.Propagation.Factory; -import brave.sampler.Sampler; -import io.micrometer.tracing.brave.bridge.BraveBaggageManager; -import io.micrometer.tracing.brave.bridge.BraveTracer; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link BraveAutoConfiguration}. - * - * @author Moritz Halbritter - */ -class BraveAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(BraveAutoConfiguration.class)); - - @Test - void shouldSupplyBraveBeans() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(Tracing.class); - assertThat(context).hasSingleBean(Tracer.class); - assertThat(context).hasSingleBean(CurrentTraceContext.class); - assertThat(context).hasSingleBean(Factory.class); - assertThat(context).hasSingleBean(Sampler.class); - }); - } - - @Test - void shouldBackOffOnCustomBraveBeans() { - this.contextRunner.withUserConfiguration(CustomBraveConfiguration.class).run((context) -> { - assertThat(context).hasBean("customTracing"); - assertThat(context).hasSingleBean(Tracing.class); - assertThat(context).hasBean("customTracer"); - assertThat(context).hasSingleBean(Tracer.class); - assertThat(context).hasBean("customCurrentTraceContext"); - assertThat(context).hasSingleBean(CurrentTraceContext.class); - assertThat(context).hasBean("customFactory"); - assertThat(context).hasSingleBean(Factory.class); - assertThat(context).hasBean("customSampler"); - assertThat(context).hasSingleBean(Sampler.class); - }); - } - - @Test - void shouldSupplyMicrometerBeans() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(BraveTracer.class); - assertThat(context).hasSingleBean(BraveBaggageManager.class); - }); - } - - @Test - void shouldBackOffOnCustomMicrometerBraveBeans() { - this.contextRunner.withUserConfiguration(CustomMicrometerBraveConfiguration.class).run((context) -> { - assertThat(context).hasBean("customBraveTracer"); - assertThat(context).hasSingleBean(BraveTracer.class); - assertThat(context).hasBean("customBraveBaggageManager"); - assertThat(context).hasSingleBean(BraveBaggageManager.class); - }); - } - - @Test - void shouldNotSupplyBraveBeansIfBraveIsMissing() { - this.contextRunner.withClassLoader(new FilteredClassLoader("brave")).run((context) -> { - assertThat(context).doesNotHaveBean(Tracing.class); - assertThat(context).doesNotHaveBean(Tracer.class); - assertThat(context).doesNotHaveBean(CurrentTraceContext.class); - assertThat(context).doesNotHaveBean(Factory.class); - assertThat(context).doesNotHaveBean(Sampler.class); - }); - } - - @Test - void shouldNotSupplyMicrometerBeansIfMicrometerIsMissing() { - this.contextRunner.withClassLoader(new FilteredClassLoader("io.micrometer")).run((context) -> { - assertThat(context).doesNotHaveBean(BraveTracer.class); - assertThat(context).doesNotHaveBean(BraveBaggageManager.class); - }); - } - - @Configuration(proxyBeanMethods = false) - private static class CustomBraveConfiguration { - - @Bean - Tracing customTracing() { - return Mockito.mock(Tracing.class); - } - - @Bean - Tracer customTracer() { - return Mockito.mock(Tracer.class); - } - - @Bean - CurrentTraceContext customCurrentTraceContext() { - return Mockito.mock(CurrentTraceContext.class); - } - - @Bean - Factory customFactory() { - return Mockito.mock(Factory.class); - } - - @Bean - Sampler customSampler() { - return Mockito.mock(Sampler.class); - } - - } - - @Configuration(proxyBeanMethods = false) - private static class CustomMicrometerBraveConfiguration { - - @Bean - BraveTracer customBraveTracer() { - return Mockito.mock(BraveTracer.class); - } - - @Bean - BraveBaggageManager customBraveBaggageManager() { - return Mockito.mock(BraveBaggageManager.class); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfigurationTests.java deleted file mode 100644 index 97e602e6bf0c..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfigurationTests.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing; - -import io.micrometer.tracing.Tracer; -import io.micrometer.tracing.handler.DefaultTracingObservationHandler; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link MicrometerTracingAutoConfiguration}. - * - * @author Moritz Halbritter - */ -class MicrometerTracingAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(MicrometerTracingAutoConfiguration.class)); - - @Test - void shouldSupplyBeans() { - this.contextRunner.withUserConfiguration(TracerConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(DefaultTracingObservationHandler.class)); - } - - @Test - void shouldBackOffOnCustomBeans() { - this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { - assertThat(context).hasBean("customDefaultTracingObservationHandler"); - assertThat(context).hasSingleBean(DefaultTracingObservationHandler.class); - }); - } - - @Test - void shouldNotSupplyBeansIfMicrometerIsMissing() { - this.contextRunner.withClassLoader(new FilteredClassLoader("io.micrometer")) - .run((context) -> assertThat(context).doesNotHaveBean(DefaultTracingObservationHandler.class)); - } - - @Test - void shouldNotSupplyDefaultTracingObservationHandlerIfTracerIsMissing() { - this.contextRunner - .run((context) -> assertThat(context).doesNotHaveBean(DefaultTracingObservationHandler.class)); - } - - @Configuration(proxyBeanMethods = false) - private static class TracerConfiguration { - - @Bean - Tracer tracer() { - return Mockito.mock(Tracer.class); - } - - } - - @Configuration(proxyBeanMethods = false) - private static class CustomConfiguration { - - @Bean - DefaultTracingObservationHandler customDefaultTracingObservationHandler() { - return Mockito.mock(DefaultTracingObservationHandler.class); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsMicrometerConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsMicrometerConfigurationTests.java deleted file mode 100644 index 6204e462d785..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsMicrometerConfigurationTests.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing; - -import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext; -import io.micrometer.tracing.otel.bridge.OtelTracer; -import io.micrometer.tracing.otel.bridge.OtelTracer.EventPublisher; -import io.opentelemetry.api.trace.Tracer; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.MicrometerConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link MicrometerConfiguration}. - * - * @author Moritz Halbritter - */ -class OpenTelemetryConfigurationsMicrometerConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(MicrometerConfiguration.class)); - - @Test - void shouldSupplyBeans() { - this.contextRunner.withUserConfiguration(TracerConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(OtelTracer.class); - assertThat(context).hasSingleBean(EventPublisher.class); - assertThat(context).hasSingleBean(OtelCurrentTraceContext.class); - }); - } - - @Test - void shouldNotSupplyBeansIfMicrometerTracingBridgeOtelIsMissing() { - this.contextRunner.withClassLoader(new FilteredClassLoader("io.micrometer.tracing.otel")) - .withUserConfiguration(TracerConfiguration.class).run((context) -> { - assertThat(context).doesNotHaveBean(OtelTracer.class); - assertThat(context).doesNotHaveBean(EventPublisher.class); - assertThat(context).doesNotHaveBean(OtelCurrentTraceContext.class); - }); - } - - @Test - void shouldNotSupplyOtelTracerIfTracerIsMissing() { - this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(OtelTracer.class)); - } - - @Test - void shouldBackOffOnCustomBeans() { - this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { - assertThat(context).hasBean("customOtelTracer"); - assertThat(context).hasSingleBean(OtelTracer.class); - assertThat(context).hasBean("customEventPublisher"); - assertThat(context).hasSingleBean(EventPublisher.class); - assertThat(context).hasBean("customOtelCurrentTraceContext"); - assertThat(context).hasSingleBean(OtelCurrentTraceContext.class); - }); - } - - @Configuration(proxyBeanMethods = false) - private static class CustomConfiguration { - - @Bean - OtelTracer customOtelTracer() { - return Mockito.mock(OtelTracer.class); - } - - @Bean - EventPublisher customEventPublisher() { - return Mockito.mock(EventPublisher.class); - } - - @Bean - OtelCurrentTraceContext customOtelCurrentTraceContext() { - return Mockito.mock(OtelCurrentTraceContext.class); - } - - } - - @Configuration(proxyBeanMethods = false) - private static class TracerConfiguration { - - @Bean - Tracer tracer() { - return Mockito.mock(Tracer.class); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsSdkConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsSdkConfigurationTests.java deleted file mode 100644 index 6930e77b87f7..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsSdkConfigurationTests.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing; - -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.context.propagation.ContextPropagators; -import io.opentelemetry.sdk.trace.SdkTracerProvider; -import io.opentelemetry.sdk.trace.SpanProcessor; -import io.opentelemetry.sdk.trace.samplers.Sampler; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.SdkConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link SdkConfiguration}. - * - * @author Moritz Halbritter - */ -class OpenTelemetryConfigurationsSdkConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(SdkConfiguration.class)); - - @Test - void shouldSupplyBeans() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(OpenTelemetry.class); - assertThat(context).hasSingleBean(SdkTracerProvider.class); - assertThat(context).hasSingleBean(ContextPropagators.class); - assertThat(context).hasSingleBean(Sampler.class); - assertThat(context).hasSingleBean(SpanProcessor.class); - }); - } - - @Test - void shouldBackOffOnCustomBeans() { - this.contextRunner.withUserConfiguration(CustomBeans.class).run((context) -> { - assertThat(context).hasBean("customOpenTelemetry"); - assertThat(context).hasSingleBean(OpenTelemetry.class); - assertThat(context).hasBean("customSdkTracerProvider"); - assertThat(context).hasSingleBean(SdkTracerProvider.class); - assertThat(context).hasBean("customContextPropagators"); - assertThat(context).hasSingleBean(ContextPropagators.class); - assertThat(context).hasBean("customSampler"); - assertThat(context).hasSingleBean(Sampler.class); - assertThat(context).hasBean("customSpanProcessor"); - assertThat(context).hasSingleBean(SpanProcessor.class); - }); - } - - @Test - void shouldNotSupplyBeansIfSdkIsMissing() { - this.contextRunner.withClassLoader(new FilteredClassLoader("io.opentelemetry.sdk")).run((context) -> { - assertThat(context).doesNotHaveBean(OpenTelemetry.class); - assertThat(context).doesNotHaveBean(SdkTracerProvider.class); - assertThat(context).doesNotHaveBean(ContextPropagators.class); - assertThat(context).doesNotHaveBean(Sampler.class); - assertThat(context).doesNotHaveBean(SpanProcessor.class); - }); - } - - private static class CustomBeans { - - @Bean - OpenTelemetry customOpenTelemetry() { - return Mockito.mock(OpenTelemetry.class); - } - - @Bean - SdkTracerProvider customSdkTracerProvider() { - return SdkTracerProvider.builder().build(); - } - - @Bean - ContextPropagators customContextPropagators() { - return Mockito.mock(ContextPropagators.class); - } - - @Bean - Sampler customSampler() { - return Mockito.mock(Sampler.class); - } - - @Bean - SpanProcessor customSpanProcessor() { - return Mockito.mock(SpanProcessor.class); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsTracerConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsTracerConfigurationTests.java deleted file mode 100644 index 2227eb89d78b..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryConfigurationsTracerConfigurationTests.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing; - -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.trace.Tracer; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryConfigurations.TracerConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link TracerConfiguration}. - * - * @author Moritz Halbritter - */ -class OpenTelemetryConfigurationsTracerConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(TracerConfiguration.class)); - - @Test - void shouldSupplyBeans() { - this.contextRunner.withUserConfiguration(OpenTelemetryConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(Tracer.class)); - } - - @Test - void shouldNotSupplyBeansIfApiIsMissing() { - this.contextRunner.withClassLoader(new FilteredClassLoader("io.opentelemetry.api")) - .run((context) -> assertThat(context).doesNotHaveBean(Tracer.class)); - } - - @Test - void shouldNotSupplyTracerIfOpenTelemetryIsMissing() { - this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(Tracer.class)); - } - - @Test - void shouldBackOffOnCustomBeans() { - this.contextRunner.withUserConfiguration(OpenTelemetryConfiguration.class, CustomConfiguration.class) - .run((context) -> { - assertThat(context).hasBean("customTracer"); - assertThat(context).hasSingleBean(Tracer.class); - }); - - } - - @Configuration(proxyBeanMethods = false) - private static class OpenTelemetryConfiguration { - - @Bean - OpenTelemetry tracer() { - return Mockito.mock(OpenTelemetry.class); - } - - } - - @Configuration(proxyBeanMethods = false) - private static class CustomConfiguration { - - @Bean - Tracer customTracer() { - return Mockito.mock(Tracer.class); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/MeterRegistrySpanMetricsTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/MeterRegistrySpanMetricsTests.java deleted file mode 100644 index cf0f3b575ac2..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/MeterRegistrySpanMetricsTests.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing.wavefront; - -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; - -import io.micrometer.core.instrument.Counter; -import io.micrometer.core.instrument.Gauge; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link MeterRegistrySpanMetrics}. - * - * @author Moritz Halbritter - */ -class MeterRegistrySpanMetricsTests { - - private SimpleMeterRegistry meterRegistry; - - private MeterRegistrySpanMetrics sut; - - @BeforeEach - void setUp() { - this.meterRegistry = new SimpleMeterRegistry(); - this.sut = new MeterRegistrySpanMetrics(this.meterRegistry); - } - - @Test - void reportDroppedShouldIncreaseCounter() { - this.sut.reportDropped(); - assertThat(getCounterValue("wavefront.reporter.spans.dropped")).isEqualTo(1); - this.sut.reportDropped(); - assertThat(getCounterValue("wavefront.reporter.spans.dropped")).isEqualTo(2); - } - - @Test - void reportReceivedShouldIncreaseCounter() { - this.sut.reportReceived(); - assertThat(getCounterValue("wavefront.reporter.spans.received")).isEqualTo(1); - this.sut.reportReceived(); - assertThat(getCounterValue("wavefront.reporter.spans.received")).isEqualTo(2); - } - - @Test - void reportErrorsShouldIncreaseCounter() { - this.sut.reportErrors(); - assertThat(getCounterValue("wavefront.reporter.errors")).isEqualTo(1); - this.sut.reportErrors(); - assertThat(getCounterValue("wavefront.reporter.errors")).isEqualTo(2); - } - - @Test - void registerQueueSizeShouldCreateGauge() { - BlockingQueue queue = new ArrayBlockingQueue(2); - this.sut.registerQueueSize(queue); - assertThat(getGaugeValue("wavefront.reporter.queue.size")).isEqualTo(0); - queue.offer(1); - assertThat(getGaugeValue("wavefront.reporter.queue.size")).isEqualTo(1); - } - - @Test - void registerQueueRemainingCapacityShouldCreateGauge() { - BlockingQueue queue = new ArrayBlockingQueue(2); - this.sut.registerQueueRemainingCapacity(queue); - assertThat(getGaugeValue("wavefront.reporter.queue.remaining_capacity")).isEqualTo(2); - queue.offer(1); - assertThat(getGaugeValue("wavefront.reporter.queue.remaining_capacity")).isEqualTo(1); - } - - private double getGaugeValue(String name) { - Gauge gauge = this.meterRegistry.find(name).gauge(); - assertThat(gauge).withFailMessage("Gauge '%s' not found", name).isNotNull(); - return gauge.value(); - } - - private double getCounterValue(String name) { - Counter counter = this.meterRegistry.find(name).counter(); - assertThat(counter).withFailMessage("Counter '%s' not found", name).isNotNull(); - return counter.count(); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfigurationTests.java deleted file mode 100644 index 5479337330b9..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfigurationTests.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing.wavefront; - -import com.wavefront.sdk.common.WavefrontSender; -import com.wavefront.sdk.common.application.ApplicationTags; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import io.micrometer.tracing.reporter.wavefront.SpanMetrics; -import io.micrometer.tracing.reporter.wavefront.WavefrontBraveSpanHandler; -import io.micrometer.tracing.reporter.wavefront.WavefrontOtelSpanHandler; -import io.micrometer.tracing.reporter.wavefront.WavefrontSpanHandler; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link WavefrontTracingAutoConfiguration}. - * - * @author Moritz Halbritter - */ -class WavefrontTracingAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(WavefrontTracingAutoConfiguration.class)); - - @Test - void shouldSupplyBeans() { - this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(ApplicationTags.class); - assertThat(context).hasSingleBean(WavefrontSpanHandler.class); - assertThat(context).hasSingleBean(SpanMetrics.class); - assertThat(context).hasSingleBean(WavefrontBraveSpanHandler.class); - assertThat(context).hasSingleBean(WavefrontOtelSpanHandler.class); - }); - } - - @Test - void shouldNotSupplyBeansIfWavefrontSenderIsMissing() { - this.contextRunner.run((context) -> { - assertThat(context).doesNotHaveBean(ApplicationTags.class); - assertThat(context).doesNotHaveBean(WavefrontSpanHandler.class); - assertThat(context).doesNotHaveBean(SpanMetrics.class); - assertThat(context).doesNotHaveBean(WavefrontBraveSpanHandler.class); - assertThat(context).doesNotHaveBean(WavefrontOtelSpanHandler.class); - }); - } - - @Test - void shouldNotSupplyBeansIfMicrometerReporterWavefrontIsMissing() { - this.contextRunner.withClassLoader(new FilteredClassLoader("io.micrometer.tracing.reporter.wavefront")) - .withUserConfiguration(WavefrontSenderConfiguration.class).run((context) -> { - assertThat(context).doesNotHaveBean(WavefrontSpanHandler.class); - assertThat(context).doesNotHaveBean(SpanMetrics.class); - assertThat(context).doesNotHaveBean(WavefrontBraveSpanHandler.class); - assertThat(context).doesNotHaveBean(WavefrontOtelSpanHandler.class); - }); - } - - @Test - void shouldSupplyMeterRegistrySpanMetricsIfMeterRegistryIsAvailable() { - this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class, MeterRegistryConfiguration.class) - .run((context) -> { - assertThat(context).hasSingleBean(SpanMetrics.class); - assertThat(context).hasSingleBean(MeterRegistrySpanMetrics.class); - }); - } - - @Test - void shouldNotSupplyWavefrontBraveSpanHandlerIfBraveIsMissing() { - this.contextRunner.withClassLoader(new FilteredClassLoader("brave")) - .withUserConfiguration(WavefrontSenderConfiguration.class) - .run((context) -> assertThat(context).doesNotHaveBean(WavefrontBraveSpanHandler.class)); - } - - @Test - void shouldNotSupplyWavefrontOtelSpanHandlerIfOtelIsMissing() { - this.contextRunner.withClassLoader(new FilteredClassLoader("io.opentelemetry.sdk.trace")) - .withUserConfiguration(WavefrontSenderConfiguration.class) - .run((context) -> assertThat(context).doesNotHaveBean(WavefrontOtelSpanHandler.class)); - } - - @Test - void shouldHaveADefaultApplicationName() { - this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class).run((context) -> { - ApplicationTags applicationTags = context.getBean(ApplicationTags.class); - assertThat(applicationTags.getApplication()).isEqualTo("application"); - }); - } - - @Test - void shouldHonorConfigProperties() { - this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class) - .withPropertyValues("spring.application.name=super-application", - "management.wavefront.tracing.service-name=super-service") - .run((context) -> { - ApplicationTags applicationTags = context.getBean(ApplicationTags.class); - assertThat(applicationTags.getApplication()).isEqualTo("super-application"); - assertThat(applicationTags.getService()).isEqualTo("super-service"); - }); - } - - @Test - void shouldBackOffOnCustomBeans() { - this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class, CustomConfiguration.class) - .run((context) -> { - assertThat(context).hasBean("customApplicationTags"); - assertThat(context).hasSingleBean(ApplicationTags.class); - assertThat(context).hasBean("customWavefrontSpanHandler"); - assertThat(context).hasSingleBean(WavefrontSpanHandler.class); - assertThat(context).hasBean("customSpanMetrics"); - assertThat(context).hasSingleBean(SpanMetrics.class); - assertThat(context).hasBean("customWavefrontBraveSpanHandler"); - assertThat(context).hasSingleBean(WavefrontBraveSpanHandler.class); - assertThat(context).hasBean("customWavefrontOtelSpanHandler"); - assertThat(context).hasSingleBean(WavefrontOtelSpanHandler.class); - }); - } - - @Configuration(proxyBeanMethods = false) - private static class CustomConfiguration { - - @Bean - ApplicationTags customApplicationTags() { - return Mockito.mock(ApplicationTags.class); - } - - @Bean - WavefrontSpanHandler customWavefrontSpanHandler() { - return Mockito.mock(WavefrontSpanHandler.class); - } - - @Bean - SpanMetrics customSpanMetrics() { - return Mockito.mock(SpanMetrics.class); - } - - @Bean - WavefrontBraveSpanHandler customWavefrontBraveSpanHandler() { - return Mockito.mock(WavefrontBraveSpanHandler.class); - } - - @Bean - WavefrontOtelSpanHandler customWavefrontOtelSpanHandler() { - return Mockito.mock(WavefrontOtelSpanHandler.class); - } - - } - - @Configuration(proxyBeanMethods = false) - private static class WavefrontSenderConfiguration { - - @Bean - WavefrontSender wavefrontSender() { - return mock(WavefrontSender.class); - } - - } - - @Configuration(proxyBeanMethods = false) - private static class MeterRegistryConfiguration { - - @Bean - MeterRegistry meterRegistry() { - return new SimpleMeterRegistry(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/NoopSender.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/NoopSender.java deleted file mode 100644 index 48a7926e7818..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/NoopSender.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; - -import java.util.List; - -import zipkin2.Call; -import zipkin2.Callback; -import zipkin2.codec.Encoding; -import zipkin2.reporter.Sender; - -class NoopSender extends Sender { - - @Override - public Encoding encoding() { - return Encoding.JSON; - } - - @Override - public int messageMaxBytes() { - return 1024; - } - - @Override - public int messageSizeInBytes(List encodedSpans) { - return encoding().listSizeInBytes(encodedSpans); - } - - @Override - public Call sendSpans(List encodedSpans) { - return new Call.Base<>() { - @Override - public Call clone() { - return this; - } - - @Override - protected Void doExecute() { - return null; - } - - @Override - protected void doEnqueue(Callback callback) { - } - }; - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfigurationTests.java deleted file mode 100644 index 4b15fdda923f..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfigurationTests.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; - -import org.junit.jupiter.api.Test; -import zipkin2.Span; -import zipkin2.codec.BytesEncoder; -import zipkin2.codec.SpanBytesEncoder; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ZipkinAutoConfiguration}. - * - * @author Moritz Halbritter - */ -class ZipkinAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(ZipkinAutoConfiguration.class)); - - @Test - void shouldSupplyBeans() { - this.contextRunner.run((context) -> assertThat(context).hasSingleBean(BytesEncoder.class)); - } - - @Test - void shouldNotSupplyBeansIfZipkinReporterIsMissing() { - this.contextRunner.withClassLoader(new FilteredClassLoader("zipkin2.reporter")) - .run((context) -> assertThat(context).doesNotHaveBean(BytesEncoder.class)); - } - - @Test - void shouldBackOffOnCustomBeans() { - this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { - assertThat(context).hasBean("customBytesEncoder"); - assertThat(context).hasSingleBean(BytesEncoder.class); - }); - } - - @Configuration(proxyBeanMethods = false) - private static class CustomConfiguration { - - @Bean - BytesEncoder customBytesEncoder() { - return SpanBytesEncoder.JSON_V2; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsBraveConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsBraveConfigurationTests.java deleted file mode 100644 index 2ac0c6f56559..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsBraveConfigurationTests.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; - -import brave.handler.SpanHandler; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import zipkin2.Span; -import zipkin2.reporter.Reporter; - -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.BraveConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link BraveConfiguration}. - * - * @author Moritz Halbritter - */ -class ZipkinConfigurationsBraveConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(BraveConfiguration.class)); - - @Test - void shouldSupplyBeans() { - this.contextRunner.withUserConfiguration(ReporterConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(SpanHandler.class)); - } - - @Test - void shouldNotSupplySpanHandlerIfReporterIsMissing() { - this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(SpanHandler.class)); - } - - @Test - void shouldNotSupplyIfZipkinReporterBraveIsNotOnClasspath() { - this.contextRunner.withClassLoader(new FilteredClassLoader("zipkin2.reporter.brave")) - .withUserConfiguration(ReporterConfiguration.class) - .run((context) -> assertThat(context).doesNotHaveBean(SpanHandler.class)); - - } - - @Test - void shouldBackOffOnCustomBeans() { - this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { - assertThat(context).hasBean("customSpanHandler"); - assertThat(context).hasSingleBean(SpanHandler.class); - }); - } - - @Configuration(proxyBeanMethods = false) - private static class ReporterConfiguration { - - @Bean - @SuppressWarnings("unchecked") - Reporter reporter() { - return Mockito.mock(Reporter.class); - } - - } - - @Configuration(proxyBeanMethods = false) - private static class CustomConfiguration { - - @Bean - SpanHandler customSpanHandler() { - return Mockito.mock(SpanHandler.class); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java deleted file mode 100644 index 14ba3e413d20..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; - -import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; -import org.junit.jupiter.api.Test; -import zipkin2.Span; -import zipkin2.codec.BytesEncoder; -import zipkin2.codec.SpanBytesEncoder; -import zipkin2.reporter.Sender; - -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.OpenTelemetryConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link OpenTelemetryConfiguration}. - * - * @author Moritz Halbritter - */ -class ZipkinConfigurationsOpenTelemetryConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(BaseConfiguration.class, OpenTelemetryConfiguration.class)); - - @Test - void shouldSupplyBeans() { - this.contextRunner.withUserConfiguration(SenderConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(ZipkinSpanExporter.class)); - } - - @Test - void shouldNotSupplyZipkinSpanExporterIfSenderIsMissing() { - this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(ZipkinSpanExporter.class)); - } - - @Test - void shouldNotSupplyZipkinSpanExporterIfNotOnClasspath() { - this.contextRunner.withClassLoader(new FilteredClassLoader("io.opentelemetry.exporter.zipkin")) - .withUserConfiguration(SenderConfiguration.class) - .run((context) -> assertThat(context).doesNotHaveBean(ZipkinSpanExporter.class)); - - } - - @Test - void shouldBackOffOnCustomBeans() { - this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { - assertThat(context).hasBean("customZipkinSpanExporter"); - assertThat(context).hasSingleBean(ZipkinSpanExporter.class); - }); - } - - @Configuration(proxyBeanMethods = false) - private static class SenderConfiguration { - - @Bean - Sender sender() { - return new NoopSender(); - } - - } - - @Configuration(proxyBeanMethods = false) - private static class CustomConfiguration { - - @Bean - ZipkinSpanExporter customZipkinSpanExporter() { - return ZipkinSpanExporter.builder().build(); - } - - } - - @Configuration(proxyBeanMethods = false) - private static class BaseConfiguration { - - @Bean - @ConditionalOnMissingBean - BytesEncoder spanBytesEncoder() { - return SpanBytesEncoder.JSON_V2; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsReporterConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsReporterConfigurationTests.java deleted file mode 100644 index e5d115927d18..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsReporterConfigurationTests.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; - -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import zipkin2.Span; -import zipkin2.codec.BytesEncoder; -import zipkin2.codec.SpanBytesEncoder; -import zipkin2.reporter.Reporter; -import zipkin2.reporter.Sender; - -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.ReporterConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ReporterConfiguration}. - * - * @author Moritz Halbritter - */ -class ZipkinConfigurationsReporterConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(BaseConfiguration.class, ReporterConfiguration.class)); - - @Test - void shouldSupplyBeans() { - this.contextRunner.withUserConfiguration(SenderConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(Reporter.class)); - } - - @Test - void shouldNotSupplyReporterIfSenderIsMissing() { - this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(Reporter.class)); - } - - @Test - void shouldBackOffOnCustomBeans() { - this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { - assertThat(context).hasBean("customReporter"); - assertThat(context).hasSingleBean(Reporter.class); - }); - } - - @Configuration(proxyBeanMethods = false) - private static class SenderConfiguration { - - @Bean - Sender sender() { - return new NoopSender(); - } - - } - - @Configuration(proxyBeanMethods = false) - private static class CustomConfiguration { - - @Bean - @SuppressWarnings("unchecked") - Reporter customReporter() { - return Mockito.mock(Reporter.class); - } - - } - - @Configuration(proxyBeanMethods = false) - private static class BaseConfiguration { - - @Bean - @ConditionalOnMissingBean - BytesEncoder spanBytesEncoder() { - return SpanBytesEncoder.JSON_V2; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsSenderConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsSenderConfigurationTests.java deleted file mode 100644 index 48a697e5c38e..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsSenderConfigurationTests.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; - -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import zipkin2.reporter.Sender; -import zipkin2.reporter.urlconnection.URLConnectionSender; - -import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.SenderConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link SenderConfiguration}. - * - * @author Moritz Halbritter - */ -class ZipkinConfigurationsSenderConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(SenderConfiguration.class)); - - @Test - void shouldSupplyBeans() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(Sender.class); - assertThat(context).hasSingleBean(URLConnectionSender.class); - assertThat(context).doesNotHaveBean(ZipkinRestTemplateSender.class); - }); - } - - @Test - void shouldUseRestTemplateSenderIfUrlConnectionSenderIsNotAvailable() { - this.contextRunner.withUserConfiguration(RestTemplateConfiguration.class) - .withClassLoader(new FilteredClassLoader("zipkin2.reporter.urlconnection")).run((context) -> { - assertThat(context).doesNotHaveBean(URLConnectionSender.class); - assertThat(context).hasSingleBean(Sender.class); - assertThat(context).hasSingleBean(ZipkinRestTemplateSender.class); - }); - } - - @Test - void shouldNotSupplyRestTemplateSenderIfNoBuilderIsAvailable() { - this.contextRunner.run((context) -> { - assertThat(context).doesNotHaveBean(ZipkinRestTemplateSender.class); - assertThat(context).hasSingleBean(Sender.class); - assertThat(context).hasSingleBean(URLConnectionSender.class); - }); - } - - @Test - void shouldBackOffOnCustomBeans() { - this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> { - assertThat(context).hasBean("customSender"); - assertThat(context).hasSingleBean(Sender.class); - }); - } - - @Configuration(proxyBeanMethods = false) - private static class RestTemplateConfiguration { - - @Bean - RestTemplateBuilder restTemplateBuilder() { - return new RestTemplateBuilder(); - } - - } - - @Configuration(proxyBeanMethods = false) - private static class CustomConfiguration { - - @Bean - Sender customSender() { - return Mockito.mock(Sender.class); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSenderTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSenderTests.java deleted file mode 100644 index 526d45be7df8..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinRestTemplateSenderTests.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.tracing.zipkin; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.List; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import zipkin2.CheckResult; -import zipkin2.reporter.ClosedSenderException; - -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.test.web.client.MockRestServiceServer; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.content; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.header; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; - -/** - * Tests for {@link ZipkinRestTemplateSender}. - * - * @author Moritz Halbritter - */ -class ZipkinRestTemplateSenderTests { - - private static final String ZIPKIN_URL = "http://localhost:9411/api/v2/spans"; - - private MockRestServiceServer mockServer; - - private ZipkinRestTemplateSender sut; - - @BeforeEach - void setUp() { - RestTemplate restTemplate = new RestTemplate(); - this.mockServer = MockRestServiceServer.createServer(restTemplate); - this.sut = new ZipkinRestTemplateSender(ZIPKIN_URL, restTemplate); - } - - @AfterEach - void tearDown() { - this.mockServer.verify(); - } - - @Test - void checkShouldSendEmptySpanList() { - this.mockServer.expect(requestTo(ZIPKIN_URL)).andExpect(method(HttpMethod.POST)) - .andExpect(content().string("[]")).andRespond(withStatus(HttpStatus.ACCEPTED)); - assertThat(this.sut.check()).isEqualTo(CheckResult.OK); - } - - @Test - void checkShouldNotRaiseException() { - this.mockServer.expect(requestTo(ZIPKIN_URL)).andExpect(method(HttpMethod.POST)) - .andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR)); - CheckResult result = this.sut.check(); - assertThat(result.ok()).isFalse(); - assertThat(result.error()).hasMessageContaining("500 Internal Server Error"); - } - - @Test - void sendSpansShouldSendSpansToZipkin() throws IOException { - this.mockServer.expect(requestTo(ZIPKIN_URL)).andExpect(method(HttpMethod.POST)) - .andExpect(content().contentType("application/json")).andExpect(content().string("[span1,span2]")) - .andRespond(withStatus(HttpStatus.ACCEPTED)); - this.sut.sendSpans(List.of(toByteArray("span1"), toByteArray("span2"))).execute(); - } - - @Test - void sendSpansShouldThrowOnHttpFailure() throws IOException { - this.mockServer.expect(requestTo(ZIPKIN_URL)).andExpect(method(HttpMethod.POST)) - .andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR)); - assertThatThrownBy(() -> this.sut.sendSpans(List.of()).execute()) - .hasMessageContaining("500 Internal Server Error"); - } - - @Test - void sendSpansShouldThrowIfCloseWasCalled() throws IOException { - this.sut.close(); - assertThatThrownBy(() -> this.sut.sendSpans(List.of())).isInstanceOf(ClosedSenderException.class); - } - - @Test - void sendSpansShouldCompressData() throws IOException { - String uncompressed = "a".repeat(10000); - // This is gzip compressed 10000 times 'a' - byte[] compressed = Base64.getDecoder() - .decode("H4sIAAAAAAAA/+3BMQ0AAAwDIKFLj/k3UR8NcA8AAAAAAAAAAAADUsAZfeASJwAA"); - this.mockServer.expect(requestTo(ZIPKIN_URL)).andExpect(method(HttpMethod.POST)) - .andExpect(header("Content-Encoding", "gzip")).andExpect(content().contentType("application/json")) - .andExpect(content().bytes(compressed)).andRespond(withStatus(HttpStatus.ACCEPTED)); - this.sut.sendSpans(List.of(toByteArray(uncompressed))).execute(); - } - - private byte[] toByteArray(String input) { - return input.getBytes(StandardCharsets.UTF_8); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfigurationTests.java deleted file mode 100644 index 2f20023e8f13..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfigurationTests.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.wavefront; - -import java.util.concurrent.LinkedBlockingQueue; - -import com.wavefront.sdk.common.WavefrontSender; -import org.assertj.core.api.InstanceOfAssertFactories; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.as; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link WavefrontAutoConfiguration}. - * - * @author Moritz Halbritter - */ -class WavefrontAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(WavefrontAutoConfiguration.class)); - - @Test - void shouldNotFailIfWavefrontIsMissing() { - this.contextRunner.withClassLoader(new FilteredClassLoader("com.wavefront")) - .run(((context) -> assertThat(context).doesNotHaveBean(WavefrontSender.class))); - } - - @Test - void failsWithoutAnApiTokenWhenPublishingDirectly() { - this.contextRunner.run((context) -> assertThat(context).hasFailed()); - } - - @Test - void defaultWavefrontSenderSettingsAreConsistent() { - this.contextRunner.withPropertyValues("management.wavefront.api-token=abcde").run((context) -> { - WavefrontProperties properties = new WavefrontProperties(); - WavefrontSender sender = context.getBean(WavefrontSender.class); - assertThat(sender) - .extracting("metricsBuffer", as(InstanceOfAssertFactories.type(LinkedBlockingQueue.class))) - .satisfies((queue) -> assertThat(queue.remainingCapacity() + queue.size()) - .isEqualTo(properties.getSender().getMaxQueueSize())); - assertThat(sender).hasFieldOrPropertyWithValue("batchSize", properties.getSender().getBatchSize()); - assertThat(sender).hasFieldOrPropertyWithValue("messageSizeBytes", - (int) properties.getSender().getMessageSize().toBytes()); - }); - } - - @Test - void configureWavefrontSender() { - this.contextRunner.withPropertyValues("management.wavefront.api-token=abcde", - "management.wavefront.sender.batch-size=50", "management.wavefront.sender.max-queue-size=100", - "management.wavefront.sender.message-size=1KB").run((context) -> { - WavefrontSender sender = context.getBean(WavefrontSender.class); - assertThat(sender).hasFieldOrPropertyWithValue("batchSize", 50); - assertThat(sender) - .extracting("metricsBuffer", as(InstanceOfAssertFactories.type(LinkedBlockingQueue.class))) - .satisfies((queue) -> assertThat(queue.remainingCapacity() + queue.size()).isEqualTo(100)); - assertThat(sender).hasFieldOrPropertyWithValue("messageSizeBytes", 1024); - }); - } - - @Test - void allowsWavefrontSenderToBeCustomized() { - this.contextRunner.withUserConfiguration(CustomSenderConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(WavefrontSender.class).hasBean("customSender")); - } - - @Configuration(proxyBeanMethods = false) - static class CustomSenderConfiguration { - - @Bean - WavefrontSender customSender() { - return mock(WavefrontSender.class); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontPropertiesTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontPropertiesTests.java deleted file mode 100644 index b5bcbd1e21ec..000000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontPropertiesTests.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.autoconfigure.wavefront; - -import java.net.URI; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -/** - * Tests for {@link WavefrontProperties}. - * - * @author Moritz Halbritter - */ -class WavefrontPropertiesTests { - - @Test - void apiTokenIsOptionalWhenUsingProxy() { - WavefrontProperties sut = new WavefrontProperties(); - sut.setUri(URI.create("proxy://localhost:2878")); - sut.setApiToken(null); - assertThat(sut.getApiTokenOrThrow()).isNull(); - assertThat(sut.getEffectiveUri()).isEqualTo(URI.create("http://localhost:2878")); - } - - @Test - void apiTokenIsMandatoryWhenNotUsingProxy() { - WavefrontProperties sut = new WavefrontProperties(); - sut.setUri(URI.create("http://localhost:2878")); - sut.setApiToken(null); - assertThat(sut.getEffectiveUri()).isEqualTo(URI.create("http://localhost:2878")); - assertThatThrownBy(sut::getApiTokenOrThrow).isInstanceOf(InvalidConfigurationPropertyValueException.class) - .hasMessageContaining("management.wavefront.api-token"); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/build.gradle b/spring-boot-project/spring-boot-actuator/build.gradle index 2a9613bb600e..15af104f6a46 100644 --- a/spring-boot-project/spring-boot-actuator/build.gradle +++ b/spring-boot-project/spring-boot-actuator/build.gradle @@ -24,6 +24,7 @@ dependencies { optional("io.lettuce:lettuce-core") optional("io.micrometer:micrometer-observation") optional("io.micrometer:micrometer-core") + optional("io.micrometer:micrometer-binders") optional("io.micrometer:micrometer-tracing-api") optional("io.micrometer:micrometer-registry-prometheus") optional("io.prometheus:simpleclient_pushgateway") { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicator.java index caf297370925..37c5601fcfd8 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicator.java @@ -26,8 +26,6 @@ import org.springframework.boot.actuate.health.Status; import org.springframework.core.ParameterizedTypeReference; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; -import org.springframework.http.HttpStatus; -import org.springframework.http.HttpStatusCode; import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.WebClient; @@ -64,16 +62,12 @@ private Mono getHealth(Health.Builder builder, WebClient webClient) { } private Mono doHealthCheck(Health.Builder builder, ClientResponse response) { - HttpStatusCode httpStatusCode = response.statusCode(); - HttpStatus httpStatus = HttpStatus.resolve(httpStatusCode.value()); - if (httpStatusCode.is2xxSuccessful()) { + if (response.statusCode().is2xxSuccessful()) { return response.bodyToMono(STRING_OBJECT_MAP).map((body) -> getHealth(builder, body)); } builder.down(); - builder.withDetail("statusCode", httpStatusCode.value()); - if (httpStatus != null) { - builder.withDetail("reasonPhrase", httpStatus.getReasonPhrase()); - } + builder.withDetail("statusCode", response.rawStatusCode()); + builder.withDetail("reasonPhrase", response.statusCode().getReasonPhrase()); return response.releaseBody().thenReturn(builder.build()); } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicator.java deleted file mode 100644 index ad1d44f2e38f..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicator.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2012-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.boot.actuate.elasticsearch; - -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.Map; - -import org.apache.http.HttpStatus; -import org.apache.http.StatusLine; -import org.elasticsearch.client.Request; -import org.elasticsearch.client.Response; -import org.elasticsearch.client.RestClient; - -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.json.JsonParser; -import org.springframework.boot.json.JsonParserFactory; -import org.springframework.util.StreamUtils; - -/** - * {@link HealthIndicator} for an Elasticsearch cluster using a {@link RestClient}. - * - * @author Artsiom Yudovin - * @author Brian Clozel - * @author Filip Hrisafov - * @since 2.7.0 - */ -public class ElasticsearchRestClientHealthIndicator extends AbstractHealthIndicator { - - private static final String RED_STATUS = "red"; - - private final RestClient client; - - private final JsonParser jsonParser; - - public ElasticsearchRestClientHealthIndicator(RestClient client) { - super("Elasticsearch health check failed"); - this.client = client; - this.jsonParser = JsonParserFactory.getJsonParser(); - } - - @Override - protected void doHealthCheck(Health.Builder builder) throws Exception { - Response response = this.client.performRequest(new Request("GET", "/_cluster/health/")); - StatusLine statusLine = response.getStatusLine(); - if (statusLine.getStatusCode() != HttpStatus.SC_OK) { - builder.down(); - builder.withDetail("statusCode", statusLine.getStatusCode()); - builder.withDetail("reasonPhrase", statusLine.getReasonPhrase()); - return; - } - try (InputStream inputStream = response.getEntity().getContent()) { - doHealthCheck(builder, StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8)); - } - } - - private void doHealthCheck(Health.Builder builder, String json) { - Map response = this.jsonParser.parseMap(json); - String status = (String) response.get("status"); - if (RED_STATUS.equals(status)) { - builder.outOfService(); - } - else { - builder.up(); - } - builder.withDetails(response); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java index 1e9f78e8e632..468f235c3b18 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java @@ -16,9 +16,22 @@ package org.springframework.boot.actuate.elasticsearch; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +import org.apache.http.HttpStatus; +import org.apache.http.StatusLine; +import org.elasticsearch.client.Request; +import org.elasticsearch.client.Response; import org.elasticsearch.client.RestClient; +import org.springframework.boot.actuate.health.AbstractHealthIndicator; +import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.json.JsonParser; +import org.springframework.boot.json.JsonParserFactory; +import org.springframework.util.StreamUtils; /** * {@link HealthIndicator} for an Elasticsearch cluster using a {@link RestClient}. @@ -27,18 +40,51 @@ * @author Brian Clozel * @author Filip Hrisafov * @since 2.1.1 - * @deprecated since 2.7.0 for removal in 2.9.0 in favor of - * {@link ElasticsearchRestClientHealthIndicator} */ -@Deprecated -public class ElasticsearchRestHealthIndicator extends ElasticsearchRestClientHealthIndicator { +public class ElasticsearchRestHealthIndicator extends AbstractHealthIndicator { + + private static final String RED_STATUS = "red"; + + private final RestClient client; + + private final JsonParser jsonParser; + @SuppressWarnings("deprecation") public ElasticsearchRestHealthIndicator(org.elasticsearch.client.RestHighLevelClient client) { this(client.getLowLevelClient()); } public ElasticsearchRestHealthIndicator(RestClient client) { - super(client); + super("Elasticsearch health check failed"); + this.client = client; + this.jsonParser = JsonParserFactory.getJsonParser(); + } + + @Override + protected void doHealthCheck(Health.Builder builder) throws Exception { + Response response = this.client.performRequest(new Request("GET", "/_cluster/health/")); + StatusLine statusLine = response.getStatusLine(); + if (statusLine.getStatusCode() != HttpStatus.SC_OK) { + builder.down(); + builder.withDetail("statusCode", statusLine.getStatusCode()); + builder.withDetail("reasonPhrase", statusLine.getReasonPhrase()); + return; + } + try (InputStream inputStream = response.getEntity().getContent()) { + doHealthCheck(builder, StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8)); + } + } + + private void doHealthCheck(Health.Builder builder, String json) { + Map response = this.jsonParser.parseMap(json); + String status = (String) response.get("status"); + if (RED_STATUS.equals(status)) { + builder.outOfService(); + } + else { + builder.up(); + } + builder.withDetails(response); } } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProvider.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProvider.java index 120bb2a06a66..71eb38bc42d2 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProvider.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProvider.java @@ -16,9 +16,9 @@ package org.springframework.boot.actuate.metrics.cache; +import io.micrometer.binder.cache.CaffeineCacheMetrics; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.binder.MeterBinder; -import io.micrometer.core.instrument.binder.cache.CaffeineCacheMetrics; import org.springframework.cache.caffeine.CaffeineCache; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java index 92894ec0f45c..f280cbe99762 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java @@ -19,9 +19,9 @@ import java.lang.reflect.Method; import com.hazelcast.spring.cache.HazelcastCache; +import io.micrometer.binder.cache.HazelcastCacheMetrics; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.binder.MeterBinder; -import io.micrometer.core.instrument.binder.cache.HazelcastCacheMetrics; import org.springframework.util.ReflectionUtils; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProvider.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProvider.java index 32550e45f8bc..5e91fb0f1eb0 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProvider.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProvider.java @@ -16,9 +16,9 @@ package org.springframework.boot.actuate.metrics.cache; +import io.micrometer.binder.cache.JCacheMetrics; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.binder.MeterBinder; -import io.micrometer.core.instrument.binder.cache.JCacheMetrics; import org.springframework.cache.jcache.JCacheCache; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListener.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListener.java index 3c6cc84cb463..90d682b34ae6 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListener.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -123,7 +123,7 @@ private void registerGauge(String name, String description, Duration timeTaken, private Iterable createTagsFrom(SpringApplication springApplication) { Class mainClass = springApplication.getMainApplicationClass(); - return (mainClass != null) ? this.tags.and("main.application.class", mainClass.getName()) : this.tags; + return (mainClass != null) ? this.tags.and("main-application-class", mainClass.getName()) : this.tags; } } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/system/DiskSpaceMetricsBinder.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/system/DiskSpaceMetricsBinder.java index d2bcf25ce0d4..b5eba5f8a130 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/system/DiskSpaceMetricsBinder.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/system/DiskSpaceMetricsBinder.java @@ -19,10 +19,10 @@ import java.io.File; import java.util.List; +import io.micrometer.binder.system.DiskSpaceMetrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.binder.MeterBinder; -import io.micrometer.core.instrument.binder.system.DiskSpaceMetrics; import org.springframework.util.Assert; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/client/RestTemplateExchangeTags.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/client/RestTemplateExchangeTags.java index f0043f5b9e0f..df7c74a50cd7 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/client/RestTemplateExchangeTags.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/client/RestTemplateExchangeTags.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -97,7 +97,7 @@ private static String getStatusMessage(ClientHttpResponse response) { if (response == null) { return "CLIENT_ERROR"; } - return String.valueOf(response.getStatusCode().value()); + return String.valueOf(response.getRawStatusCode()); } catch (IOException ex) { return "IO_ERROR"; @@ -105,17 +105,17 @@ private static String getStatusMessage(ClientHttpResponse response) { } /** - * Create a {@code client.name} {@code Tag} derived from the {@link URI#getHost host} + * Create a {@code clientName} {@code Tag} derived from the {@link URI#getHost host} * of the {@link HttpRequest#getURI() URI} of the given {@code request}. * @param request the request - * @return the client.name tag + * @return the clientName tag */ public static Tag clientName(HttpRequest request) { String host = request.getURI().getHost(); if (host == null) { host = "none"; } - return Tag.of("client.name", host); + return Tag.of("clientName", host); } /** @@ -128,7 +128,7 @@ public static Tag clientName(HttpRequest request) { public static Tag outcome(ClientHttpResponse response) { try { if (response != null) { - return Outcome.forStatus(response.getStatusCode().value()).asTag(); + return Outcome.forStatus(response.getRawStatusCode()).asTag(); } } catch (IOException ex) { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyConnectionMetricsBinder.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyConnectionMetricsBinder.java index 2f3483da5850..662dd2ad2307 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyConnectionMetricsBinder.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyConnectionMetricsBinder.java @@ -18,9 +18,9 @@ import java.util.Collections; +import io.micrometer.binder.jetty.JettyConnectionMetrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; -import io.micrometer.core.instrument.binder.jetty.JettyConnectionMetrics; import org.eclipse.jetty.server.Server; /** diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyServerThreadPoolMetricsBinder.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyServerThreadPoolMetricsBinder.java index 2297b4f96ae4..4801f05ebd58 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyServerThreadPoolMetricsBinder.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettyServerThreadPoolMetricsBinder.java @@ -18,9 +18,9 @@ import java.util.Collections; +import io.micrometer.binder.jetty.JettyServerThreadPoolMetrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; -import io.micrometer.core.instrument.binder.jetty.JettyServerThreadPoolMetrics; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.thread.ThreadPool; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettySslHandshakeMetricsBinder.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettySslHandshakeMetricsBinder.java index f4c81814a05c..f590d24ffe9c 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettySslHandshakeMetricsBinder.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/jetty/JettySslHandshakeMetricsBinder.java @@ -18,9 +18,9 @@ import java.util.Collections; +import io.micrometer.binder.jetty.JettySslHandshakeMetrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; -import io.micrometer.core.instrument.binder.jetty.JettySslHandshakeMetrics; import org.eclipse.jetty.server.Server; /** diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTags.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTags.java index ac11b00e39be..6d0af88c6b7e 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTags.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTags.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -45,7 +45,7 @@ public final class WebClientExchangeTags { private static final Pattern PATTERN_BEFORE_PATH = Pattern.compile("^https?://[^/]+/"); - private static final Tag CLIENT_NAME_NONE = Tag.of("client.name", "none"); + private static final Tag CLIENT_NAME_NONE = Tag.of("clientName", "none"); private WebClientExchangeTags() { } @@ -86,7 +86,7 @@ private static String extractPath(String url) { */ public static Tag status(ClientResponse response, Throwable throwable) { if (response != null) { - return Tag.of("status", String.valueOf(response.statusCode().value())); + return Tag.of("status", String.valueOf(response.rawStatusCode())); } if (throwable != null) { return (throwable instanceof IOException) ? IO_ERROR : CLIENT_ERROR; @@ -95,18 +95,18 @@ public static Tag status(ClientResponse response, Throwable throwable) { } /** - * Create a {@code client.name} {@code Tag} derived from the + * Create a {@code clientName} {@code Tag} derived from the * {@link java.net.URI#getHost host} of the {@link ClientRequest#url() URL} of the * given {@code request}. * @param request the request - * @return the client.name tag + * @return the clientName tag */ public static Tag clientName(ClientRequest request) { String host = request.url().getHost(); if (host == null) { return CLIENT_NAME_NONE; } - return Tag.of("client.name", host); + return Tag.of("clientName", host); } /** @@ -117,7 +117,7 @@ public static Tag clientName(ClientRequest request) { * @since 2.2.0 */ public static Tag outcome(ClientResponse response) { - Outcome outcome = (response != null) ? Outcome.forStatus(response.statusCode().value()) : Outcome.UNKNOWN; + Outcome outcome = (response != null) ? Outcome.forStatus(response.rawStatusCode()) : Outcome.UNKNOWN; return outcome.asTag(); } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTags.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTags.java index 7b55fff6b482..ce9205f9d0f1 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTags.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTags.java @@ -25,7 +25,7 @@ import org.springframework.boot.actuate.metrics.http.Outcome; import org.springframework.http.HttpStatus; -import org.springframework.http.HttpStatusCode; +import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.util.StringUtils; import org.springframework.web.reactive.HandlerMapping; import org.springframework.web.server.ServerWebExchange; @@ -80,7 +80,7 @@ public static Tag method(ServerWebExchange exchange) { * @return the status tag derived from the response status */ public static Tag status(ServerWebExchange exchange) { - HttpStatusCode status = exchange.getResponse().getStatusCode(); + HttpStatus status = exchange.getResponse().getStatusCode(); if (status == null) { status = HttpStatus.OK; } @@ -122,7 +122,7 @@ public static Tag uri(ServerWebExchange exchange, boolean ignoreTrailingSlash) { } return Tag.of("uri", patternString); } - HttpStatusCode status = exchange.getResponse().getStatusCode(); + HttpStatus status = exchange.getResponse().getStatusCode(); if (status != null) { if (status.is3xxRedirection()) { return URI_REDIRECTION; @@ -181,9 +181,19 @@ public static Tag outcome(ServerWebExchange exchange, Throwable exception) { return Outcome.UNKNOWN.asTag(); } } - HttpStatusCode statusCode = exchange.getResponse().getStatusCode(); - Outcome outcome = (statusCode != null) ? Outcome.forStatus(statusCode.value()) : Outcome.SUCCESS; + Integer statusCode = extractStatusCode(exchange); + Outcome outcome = (statusCode != null) ? Outcome.forStatus(statusCode) : Outcome.SUCCESS; return outcome.asTag(); } + private static Integer extractStatusCode(ServerWebExchange exchange) { + ServerHttpResponse response = exchange.getResponse(); + Integer statusCode = response.getRawStatusCode(); + if (statusCode != null) { + return statusCode; + } + HttpStatus status = response.getStatusCode(); + return (status != null) ? status.value() : null; + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/tomcat/TomcatMetricsBinder.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/tomcat/TomcatMetricsBinder.java index 45ad5a4acf5d..1de4181edaf2 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/tomcat/TomcatMetricsBinder.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/tomcat/TomcatMetricsBinder.java @@ -18,9 +18,9 @@ import java.util.Collections; +import io.micrometer.binder.tomcat.TomcatMetrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; -import io.micrometer.core.instrument.binder.tomcat.TomcatMetrics; import org.apache.catalina.Container; import org.apache.catalina.Context; import org.apache.catalina.Manager; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicatorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicatorTests.java index 9c6ab674c132..c1e56b7e56c9 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchReactiveHealthIndicatorTests.java @@ -16,7 +16,6 @@ package org.springframework.boot.actuate.elasticsearch; -import java.time.Duration; import java.util.Map; import okhttp3.mockwebserver.MockResponse; @@ -45,8 +44,6 @@ */ class ElasticsearchReactiveHealthIndicatorTests { - private static final Duration TIMEOUT = Duration.ofSeconds(5); - private MockWebServer server; private ElasticsearchReactiveHealthIndicator healthIndicator; @@ -68,7 +65,7 @@ void shutdown() throws Exception { @Test void elasticsearchIsUp() { setupMockResponse(200, "green"); - Health health = this.healthIndicator.health().block(TIMEOUT); + Health health = this.healthIndicator.health().block(); assertThat(health.getStatus()).isEqualTo(Status.UP); assertHealthDetailsWithStatus(health.getDetails(), "green"); } @@ -76,7 +73,7 @@ void elasticsearchIsUp() { @Test void elasticsearchWithYellowStatusIsUp() { setupMockResponse(200, "yellow"); - Health health = this.healthIndicator.health().block(TIMEOUT); + Health health = this.healthIndicator.health().block(); assertThat(health.getStatus()).isEqualTo(Status.UP); assertHealthDetailsWithStatus(health.getDetails(), "yellow"); } @@ -84,7 +81,7 @@ void elasticsearchWithYellowStatusIsUp() { @Test void elasticsearchIsDown() throws Exception { this.server.shutdown(); - Health health = this.healthIndicator.health().block(TIMEOUT); + Health health = this.healthIndicator.health().block(); assertThat(health.getStatus()).isEqualTo(Status.DOWN); assertThat(health.getDetails().get("error")).asString() .contains("org.springframework.data.elasticsearch.client.NoReachableHostException"); @@ -96,7 +93,7 @@ void elasticsearchIsDownByResponseCode() { // to "/" this.server.enqueue(new MockResponse().setResponseCode(HttpStatus.OK.value())); this.server.enqueue(new MockResponse().setResponseCode(HttpStatus.INTERNAL_SERVER_ERROR.value())); - Health health = this.healthIndicator.health().block(TIMEOUT); + Health health = this.healthIndicator.health().block(); assertThat(health.getStatus()).isEqualTo(Status.DOWN); assertThat(health.getDetails().get("statusCode")).asString().isEqualTo("500"); assertThat(health.getDetails().get("reasonPhrase")).asString().isEqualTo("Internal Server Error"); @@ -105,7 +102,7 @@ void elasticsearchIsDownByResponseCode() { @Test void elasticsearchIsOutOfServiceByStatus() { setupMockResponse(200, "red"); - Health health = this.healthIndicator.health().block(TIMEOUT); + Health health = this.healthIndicator.health().block(); assertThat(health.getStatus()).isEqualTo(Status.OUT_OF_SERVICE); assertHealthDetailsWithStatus(health.getDetails(), "red"); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicatorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorTests.java similarity index 90% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicatorTests.java rename to spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorTests.java index a718c6dc9119..c283c049e2b3 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestClientHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorTests.java @@ -37,16 +37,16 @@ import static org.mockito.Mockito.mock; /** - * Tests for {@link ElasticsearchRestClientHealthIndicator}. + * Tests for {@link ElasticsearchRestHealthIndicator}. * * @author Artsiom Yudovin * @author Filip Hrisafov */ -class ElasticsearchRestClientHealthIndicatorTests { +class ElasticsearchRestHealthIndicatorTests { private final RestClient restClient = mock(RestClient.class); - private final ElasticsearchRestClientHealthIndicator elasticsearchRestClientHealthIndicator = new ElasticsearchRestClientHealthIndicator( + private final ElasticsearchRestHealthIndicator elasticsearchRestHealthIndicator = new ElasticsearchRestHealthIndicator( this.restClient); @Test @@ -59,7 +59,7 @@ void elasticsearchIsUp() throws IOException { given(response.getStatusLine()).willReturn(statusLine); given(response.getEntity()).willReturn(httpEntity); given(this.restClient.performRequest(any(Request.class))).willReturn(response); - Health health = this.elasticsearchRestClientHealthIndicator.health(); + Health health = this.elasticsearchRestHealthIndicator.health(); assertThat(health.getStatus()).isEqualTo(Status.UP); assertHealthDetailsWithStatus(health.getDetails(), "green"); } @@ -74,7 +74,7 @@ void elasticsearchWithYellowStatusIsUp() throws IOException { given(response.getStatusLine()).willReturn(statusLine); given(response.getEntity()).willReturn(httpEntity); given(this.restClient.performRequest(any(Request.class))).willReturn(response); - Health health = this.elasticsearchRestClientHealthIndicator.health(); + Health health = this.elasticsearchRestHealthIndicator.health(); assertThat(health.getStatus()).isEqualTo(Status.UP); assertHealthDetailsWithStatus(health.getDetails(), "yellow"); } @@ -82,7 +82,7 @@ void elasticsearchWithYellowStatusIsUp() throws IOException { @Test void elasticsearchIsDown() throws IOException { given(this.restClient.performRequest(any(Request.class))).willThrow(new IOException("Couldn't connect")); - Health health = this.elasticsearchRestClientHealthIndicator.health(); + Health health = this.elasticsearchRestHealthIndicator.health(); assertThat(health.getStatus()).isEqualTo(Status.DOWN); assertThat(health.getDetails()).contains(entry("error", "java.io.IOException: Couldn't connect")); } @@ -95,7 +95,7 @@ void elasticsearchIsDownByResponseCode() throws IOException { given(statusLine.getReasonPhrase()).willReturn("Internal server error"); given(response.getStatusLine()).willReturn(statusLine); given(this.restClient.performRequest(any(Request.class))).willReturn(response); - Health health = this.elasticsearchRestClientHealthIndicator.health(); + Health health = this.elasticsearchRestHealthIndicator.health(); assertThat(health.getStatus()).isEqualTo(Status.DOWN); assertThat(health.getDetails()).contains(entry("statusCode", 500), entry("reasonPhrase", "Internal server error")); @@ -111,7 +111,7 @@ void elasticsearchIsOutOfServiceByStatus() throws IOException { given(response.getStatusLine()).willReturn(statusLine); given(response.getEntity()).willReturn(httpEntity); given(this.restClient.performRequest(any(Request.class))).willReturn(response); - Health health = this.elasticsearchRestClientHealthIndicator.health(); + Health health = this.elasticsearchRestHealthIndicator.health(); assertThat(health.getStatus()).isEqualTo(Status.OUT_OF_SERVICE); assertHealthDetailsWithStatus(health.getDetails(), "red"); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java index b29425aeab72..583cae025846 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java @@ -21,9 +21,9 @@ import java.util.Map; import com.fasterxml.jackson.databind.ObjectMapper; +import io.micrometer.binder.jvm.JvmMemoryMetrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.MockClock; -import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; import io.micrometer.core.instrument.simple.SimpleConfig; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProviderTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProviderTests.java index bca5ce345b7c..d4246cf3402e 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProviderTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/CaffeineCacheMeterBinderProviderTests.java @@ -19,8 +19,8 @@ import java.util.Collections; import com.github.benmanes.caffeine.cache.Caffeine; +import io.micrometer.binder.cache.CaffeineCacheMetrics; import io.micrometer.core.instrument.binder.MeterBinder; -import io.micrometer.core.instrument.binder.cache.CaffeineCacheMetrics; import org.junit.jupiter.api.Test; import org.springframework.cache.caffeine.CaffeineCache; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderTests.java index 737e8b855b9e..d5b57e21a494 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderTests.java @@ -20,8 +20,8 @@ import com.hazelcast.map.IMap; import com.hazelcast.spring.cache.HazelcastCache; +import io.micrometer.binder.cache.HazelcastCacheMetrics; import io.micrometer.core.instrument.binder.MeterBinder; -import io.micrometer.core.instrument.binder.cache.HazelcastCacheMetrics; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProviderTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProviderTests.java index 919dc5bb06c5..8d9a8f00158d 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProviderTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/JCacheCacheMeterBinderProviderTests.java @@ -20,8 +20,8 @@ import java.net.URISyntaxException; import java.util.Collections; +import io.micrometer.binder.cache.JCacheMetrics; import io.micrometer.core.instrument.binder.MeterBinder; -import io.micrometer.core.instrument.binder.cache.JCacheMetrics; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListenerTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListenerTests.java index 8c0cd13534a3..34763a6fbcdf 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListenerTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/startup/StartupTimeMetricsListenerTests.java @@ -118,7 +118,7 @@ private void assertMetricExistsWithValue(String metricName, long expectedValueIn private void assertMetricExistsWithCustomTagsAndValue(String metricName, Tags expectedCustomTags, Long expectedValueInMillis) { assertThat(this.registry.find(metricName) - .tags(Tags.concat(expectedCustomTags, "main.application.class", TestMainApplication.class.getName())) + .tags(Tags.concat(expectedCustomTags, "main-application-class", TestMainApplication.class.getName())) .timeGauge()).isNotNull().extracting((m) -> m.value(TimeUnit.MILLISECONDS)) .isEqualTo(expectedValueInMillis.doubleValue()); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/RestTemplateExchangeTagsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/RestTemplateExchangeTagsTests.java index 1a495a841899..17be58c70317 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/RestTemplateExchangeTagsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/RestTemplateExchangeTagsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -17,14 +17,11 @@ package org.springframework.boot.actuate.metrics.web.client; import java.io.IOException; -import java.net.URI; import io.micrometer.core.instrument.Tag; import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; -import org.springframework.http.HttpStatusCode; -import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpResponse; import org.springframework.mock.http.client.MockClientHttpResponse; @@ -84,7 +81,7 @@ void outcomeTagIsServerErrorWhenResponseIs5xx() { @Test void outcomeTagIsUnknownWhenResponseThrowsIOException() throws Exception { ClientHttpResponse response = mock(ClientHttpResponse.class); - given(response.getStatusCode()).willThrow(IOException.class); + given(response.getRawStatusCode()).willThrow(IOException.class); Tag tag = RestTemplateExchangeTags.outcome(response); assertThat(tag.getValue()).isEqualTo("UNKNOWN"); } @@ -92,7 +89,7 @@ void outcomeTagIsUnknownWhenResponseThrowsIOException() throws Exception { @Test void outcomeTagIsClientErrorWhenResponseIsNonStandardInClientSeries() throws IOException { ClientHttpResponse response = mock(ClientHttpResponse.class); - given(response.getStatusCode()).willReturn(HttpStatusCode.valueOf(490)); + given(response.getRawStatusCode()).willReturn(490); Tag tag = RestTemplateExchangeTags.outcome(response); assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR"); } @@ -100,17 +97,9 @@ void outcomeTagIsClientErrorWhenResponseIsNonStandardInClientSeries() throws IOE @Test void outcomeTagIsUnknownWhenResponseStatusIsInUnknownSeries() throws IOException { ClientHttpResponse response = mock(ClientHttpResponse.class); - given(response.getStatusCode()).willReturn(HttpStatusCode.valueOf(701)); + given(response.getRawStatusCode()).willReturn(701); Tag tag = RestTemplateExchangeTags.outcome(response); assertThat(tag.getValue()).isEqualTo("UNKNOWN"); } - @Test - void clientNameTagIsHostOfRequestUri() throws IOException { - ClientHttpRequest request = mock(ClientHttpRequest.class); - given(request.getURI()).willReturn(URI.create("https://example.org")); - Tag tag = RestTemplateExchangeTags.clientName(request); - assertThat(tag).isEqualTo(Tag.of("client.name", "example.org")); - } - } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/DefaultWebClientExchangeTagsProviderTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/DefaultWebClientExchangeTagsProviderTests.java index d01b7d9cb7af..5358fd357762 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/DefaultWebClientExchangeTagsProviderTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/DefaultWebClientExchangeTagsProviderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2020 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. @@ -54,14 +54,14 @@ void setup() { this.request = ClientRequest.create(HttpMethod.GET, URI.create("https://example.org/projects/spring-boot")) .attribute(URI_TEMPLATE_ATTRIBUTE, "https://example.org/projects/{project}").build(); this.response = mock(ClientResponse.class); - given(this.response.statusCode()).willReturn(HttpStatus.OK); + given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value()); } @Test void tagsShouldBePopulated() { Iterable tags = this.tagsProvider.tags(this.request, this.response, null); assertThat(tags).containsExactlyInAnyOrder(Tag.of("method", "GET"), Tag.of("uri", "/projects/{project}"), - Tag.of("client.name", "example.org"), Tag.of("status", "200"), Tag.of("outcome", "SUCCESS")); + Tag.of("clientName", "example.org"), Tag.of("status", "200"), Tag.of("outcome", "SUCCESS")); } @Test @@ -70,28 +70,28 @@ void tagsWhenNoUriTemplateShouldProvideUriPath() { .create(HttpMethod.GET, URI.create("https://example.org/projects/spring-boot")).build(); Iterable tags = this.tagsProvider.tags(request, this.response, null); assertThat(tags).containsExactlyInAnyOrder(Tag.of("method", "GET"), Tag.of("uri", "/projects/spring-boot"), - Tag.of("client.name", "example.org"), Tag.of("status", "200"), Tag.of("outcome", "SUCCESS")); + Tag.of("clientName", "example.org"), Tag.of("status", "200"), Tag.of("outcome", "SUCCESS")); } @Test void tagsWhenIoExceptionShouldReturnIoErrorStatus() { Iterable tags = this.tagsProvider.tags(this.request, null, new IOException()); assertThat(tags).containsExactlyInAnyOrder(Tag.of("method", "GET"), Tag.of("uri", "/projects/{project}"), - Tag.of("client.name", "example.org"), Tag.of("status", "IO_ERROR"), Tag.of("outcome", "UNKNOWN")); + Tag.of("clientName", "example.org"), Tag.of("status", "IO_ERROR"), Tag.of("outcome", "UNKNOWN")); } @Test void tagsWhenExceptionShouldReturnClientErrorStatus() { Iterable tags = this.tagsProvider.tags(this.request, null, new IllegalArgumentException()); assertThat(tags).containsExactlyInAnyOrder(Tag.of("method", "GET"), Tag.of("uri", "/projects/{project}"), - Tag.of("client.name", "example.org"), Tag.of("status", "CLIENT_ERROR"), Tag.of("outcome", "UNKNOWN")); + Tag.of("clientName", "example.org"), Tag.of("status", "CLIENT_ERROR"), Tag.of("outcome", "UNKNOWN")); } @Test void tagsWhenCancelledRequestShouldReturnClientErrorStatus() { Iterable tags = this.tagsProvider.tags(this.request, null, null); assertThat(tags).containsExactlyInAnyOrder(Tag.of("method", "GET"), Tag.of("uri", "/projects/{project}"), - Tag.of("client.name", "example.org"), Tag.of("status", "CLIENT_ERROR"), Tag.of("outcome", "UNKNOWN")); + Tag.of("clientName", "example.org"), Tag.of("status", "CLIENT_ERROR"), Tag.of("outcome", "UNKNOWN")); } } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/MetricsWebClientFilterFunctionTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/MetricsWebClientFilterFunctionTests.java index f762b6850f7d..b651560ec57c 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/MetricsWebClientFilterFunctionTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/MetricsWebClientFilterFunctionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -75,7 +75,7 @@ void setup() { void filterShouldRecordTimer() { ClientRequest request = ClientRequest .create(HttpMethod.GET, URI.create("https://example.com/projects/spring-boot")).build(); - given(this.response.statusCode()).willReturn(HttpStatus.OK); + given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value()); this.filterFunction.filter(request, this.exchange).block(Duration.ofSeconds(5)); assertThat(this.registry.get("http.client.requests") .tags("method", "GET", "uri", "/projects/spring-boot", "status", "200").timer().count()).isEqualTo(1); @@ -86,7 +86,7 @@ void filterWhenUriTemplatePresentShouldRecordTimer() { ClientRequest request = ClientRequest .create(HttpMethod.GET, URI.create("https://example.com/projects/spring-boot")) .attribute(URI_TEMPLATE_ATTRIBUTE, "/projects/{project}").build(); - given(this.response.statusCode()).willReturn(HttpStatus.OK); + given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value()); this.filterFunction.filter(request, this.exchange).block(Duration.ofSeconds(5)); assertThat(this.registry.get("http.client.requests") .tags("method", "GET", "uri", "/projects/{project}", "status", "200").timer().count()).isEqualTo(1); @@ -120,7 +120,7 @@ void filterWhenExceptionThrownShouldRecordTimer() { void filterWhenCancelThrownShouldRecordTimer() { ClientRequest request = ClientRequest .create(HttpMethod.GET, URI.create("https://example.com/projects/spring-boot")).build(); - given(this.response.statusCode()).willReturn(HttpStatus.OK); + given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value()); Mono filter = this.filterFunction.filter(request, this.exchange); StepVerifier.create(filter).thenCancel().verify(Duration.ofSeconds(5)); assertThat(this.registry.get("http.client.requests") @@ -135,7 +135,7 @@ void filterWhenCancelThrownShouldRecordTimer() { void filterWhenCancelAfterResponseThrownShouldNotRecordTimer() { ClientRequest request = ClientRequest .create(HttpMethod.GET, URI.create("https://example.com/projects/spring-boot")).build(); - given(this.response.statusCode()).willReturn(HttpStatus.OK); + given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value()); Mono filter = this.filterFunction.filter(request, this.exchange); StepVerifier.create(filter).expectNextCount(1).thenCancel().verify(Duration.ofSeconds(5)); assertThat(this.registry.get("http.client.requests") diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTagsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTagsTests.java index 9889ba7d2174..3ba0a4eed9e8 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTagsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTagsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2020 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. @@ -25,7 +25,6 @@ import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; -import org.springframework.http.HttpStatusCode; import org.springframework.web.reactive.function.client.ClientRequest; import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.WebClient; @@ -89,12 +88,12 @@ void uriWhenTemplateIsMissingShouldReturnPathWithQueryParams() { @Test void clientName() { - assertThat(WebClientExchangeTags.clientName(this.request)).isEqualTo(Tag.of("client.name", "example.org")); + assertThat(WebClientExchangeTags.clientName(this.request)).isEqualTo(Tag.of("clientName", "example.org")); } @Test void status() { - given(this.response.statusCode()).willReturn(HttpStatus.OK); + given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value()); assertThat(WebClientExchangeTags.status(this.response, null)).isEqualTo(Tag.of("status", "200")); } @@ -111,7 +110,7 @@ void statusWhenClientException() { @Test void statusWhenNonStandard() { - given(this.response.statusCode()).willReturn(HttpStatusCode.valueOf(490)); + given(this.response.rawStatusCode()).willReturn(490); assertThat(WebClientExchangeTags.status(this.response, null)).isEqualTo(Tag.of("status", "490")); } @@ -128,49 +127,49 @@ void outcomeTagIsUnknownWhenResponseIsNull() { @Test void outcomeTagIsInformationalWhenResponseIs1xx() { - given(this.response.statusCode()).willReturn(HttpStatus.CONTINUE); + given(this.response.rawStatusCode()).willReturn(HttpStatus.CONTINUE.value()); Tag tag = WebClientExchangeTags.outcome(this.response); assertThat(tag.getValue()).isEqualTo("INFORMATIONAL"); } @Test void outcomeTagIsSuccessWhenResponseIs2xx() { - given(this.response.statusCode()).willReturn(HttpStatus.OK); + given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value()); Tag tag = WebClientExchangeTags.outcome(this.response); assertThat(tag.getValue()).isEqualTo("SUCCESS"); } @Test void outcomeTagIsRedirectionWhenResponseIs3xx() { - given(this.response.statusCode()).willReturn(HttpStatus.MOVED_PERMANENTLY); + given(this.response.rawStatusCode()).willReturn(HttpStatus.MOVED_PERMANENTLY.value()); Tag tag = WebClientExchangeTags.outcome(this.response); assertThat(tag.getValue()).isEqualTo("REDIRECTION"); } @Test void outcomeTagIsClientErrorWhenResponseIs4xx() { - given(this.response.statusCode()).willReturn(HttpStatus.BAD_REQUEST); + given(this.response.rawStatusCode()).willReturn(HttpStatus.BAD_REQUEST.value()); Tag tag = WebClientExchangeTags.outcome(this.response); assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR"); } @Test void outcomeTagIsServerErrorWhenResponseIs5xx() { - given(this.response.statusCode()).willReturn(HttpStatus.BAD_GATEWAY); + given(this.response.rawStatusCode()).willReturn(HttpStatus.BAD_GATEWAY.value()); Tag tag = WebClientExchangeTags.outcome(this.response); assertThat(tag.getValue()).isEqualTo("SERVER_ERROR"); } @Test void outcomeTagIsClientErrorWhenResponseIsNonStandardInClientSeries() { - given(this.response.statusCode()).willReturn(HttpStatusCode.valueOf(490)); + given(this.response.rawStatusCode()).willReturn(490); Tag tag = WebClientExchangeTags.outcome(this.response); assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR"); } @Test void outcomeTagIsUnknownWhenResponseStatusIsInUnknownSeries() { - given(this.response.statusCode()).willReturn(HttpStatusCode.valueOf(701)); + given(this.response.rawStatusCode()).willReturn(701); Tag tag = WebClientExchangeTags.outcome(this.response); assertThat(tag.getValue()).isEqualTo("UNKNOWN"); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTagsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTagsTests.java index c82b1a22e3d4..c6e04f9a6ebc 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTagsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTagsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -153,7 +153,7 @@ void outcomeTagIsSuccessWhenResponseStatusIsAvailableFromUnderlyingServer() { ServerHttpRequest request = mock(ServerHttpRequest.class); ServerHttpResponse response = mock(ServerHttpResponse.class); given(response.getStatusCode()).willReturn(HttpStatus.OK); - given(response.getStatusCode().value()).willReturn(null); + given(response.getRawStatusCode()).willReturn(null); given(exchange.getRequest()).willReturn(request); given(exchange.getResponse()).willReturn(response); Tag tag = WebFluxTags.outcome(exchange, null); diff --git a/spring-boot-project/spring-boot-autoconfigure/build.gradle b/spring-boot-project/spring-boot-autoconfigure/build.gradle index 0e741597ee0b..8a8a20c37aa5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-autoconfigure/build.gradle @@ -214,7 +214,6 @@ dependencies { testImplementation("org.junit.jupiter:junit-jupiter") testImplementation("org.mockito:mockito-core") testImplementation("org.mockito:mockito-junit-jupiter") - testImplementation("org.skyscreamer:jsonassert") testImplementation("org.springframework:spring-test") testImplementation("org.springframework.kafka:spring-kafka-test") testImplementation("org.springframework.security:spring-security-test") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzer.java index 728a0c91e866..ef174a22af4b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzer.java @@ -26,7 +26,9 @@ import java.util.Set; import java.util.stream.Collectors; +import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.InjectionPoint; import org.springframework.beans.factory.NoSuchBeanDefinitionException; @@ -55,17 +57,18 @@ * * @author Stephane Nicoll * @author Phillip Webb - * @author Scott Frederick */ -class NoSuchBeanDefinitionFailureAnalyzer extends AbstractInjectionFailureAnalyzer { +class NoSuchBeanDefinitionFailureAnalyzer extends AbstractInjectionFailureAnalyzer + implements BeanFactoryAware { - private final ConfigurableListableBeanFactory beanFactory; + private ConfigurableListableBeanFactory beanFactory; - private final MetadataReaderFactory metadataReaderFactory; + private MetadataReaderFactory metadataReaderFactory; - private final ConditionEvaluationReport report; + private ConditionEvaluationReport report; - NoSuchBeanDefinitionFailureAnalyzer(BeanFactory beanFactory) { + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { Assert.isInstanceOf(ConfigurableListableBeanFactory.class, beanFactory); this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; this.metadataReaderFactory = new CachingMetadataReaderFactory(this.beanFactory.getBeanClassLoader()); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfiguration.java index a219abf00025..988f5115e7d7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfiguration.java @@ -22,8 +22,6 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientBuilderConfiguration; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientConfiguration; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientFromRestHighLevelClientConfiguration; import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientSnifferConfiguration; import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestHighLevelClientConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -40,7 +38,6 @@ @ConditionalOnClass(RestClientBuilder.class) @EnableConfigurationProperties({ ElasticsearchProperties.class, ElasticsearchRestClientProperties.class }) @Import({ RestClientBuilderConfiguration.class, RestHighLevelClientConfiguration.class, - RestClientFromRestHighLevelClientConfiguration.class, RestClientConfiguration.class, RestClientSnifferConfiguration.class }) public class ElasticsearchRestClientAutoConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientConfigurations.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientConfigurations.java index 903a4dc23f31..31776e8096a7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientConfigurations.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientConfigurations.java @@ -35,7 +35,6 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.context.annotation.Bean; @@ -46,7 +45,6 @@ * Elasticsearch rest client configurations. * * @author Stephane Nicoll - * @author Filip Hrisafov */ class ElasticsearchRestClientConfigurations { @@ -124,40 +122,16 @@ org.elasticsearch.client.RestHighLevelClient elasticsearchRestHighLevelClient( } @SuppressWarnings("deprecation") - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(org.elasticsearch.client.RestHighLevelClient.class) - @ConditionalOnSingleCandidate(org.elasticsearch.client.RestHighLevelClient.class) - @ConditionalOnMissingBean(RestClient.class) - static class RestClientFromRestHighLevelClientConfiguration { - - @Bean - RestClient elasticsearchRestClient(org.elasticsearch.client.RestHighLevelClient restHighLevelClient) { - return restHighLevelClient.getLowLevelClient(); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnMissingClass("org.elasticsearch.client.RestHighLevelClient") - @ConditionalOnMissingBean(RestClient.class) - static class RestClientConfiguration { - - @Bean - RestClient elasticsearchRestClient(RestClientBuilder restClientBuilder) { - return restClientBuilder.build(); - } - - } - @Configuration(proxyBeanMethods = false) @ConditionalOnClass(Sniffer.class) - @ConditionalOnSingleCandidate(RestClient.class) + @ConditionalOnSingleCandidate(org.elasticsearch.client.RestHighLevelClient.class) static class RestClientSnifferConfiguration { @Bean @ConditionalOnMissingBean - Sniffer elasticsearchSniffer(RestClient client, ElasticsearchRestClientProperties properties) { - SnifferBuilder builder = Sniffer.builder(client); + Sniffer elasticsearchSniffer(org.elasticsearch.client.RestHighLevelClient client, + ElasticsearchRestClientProperties properties) { + SnifferBuilder builder = Sniffer.builder(client.getLowLevelClient()); PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); Duration interval = properties.getSniffer().getInterval(); map.from(interval).asInt(Duration::toMillis).to(builder::setSniffIntervalMillis); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java index 96da586a59ce..711a12bce70c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java @@ -325,6 +325,15 @@ private void configureJavaMigrations(FluentConfiguration flyway, List locations) { + for (String location : locations) { + if (resourceLoader.getResource(normalizePrefix(location)).exists()) { + return true; + } + } + return false; + } + private String normalizePrefix(String location) { return location.replace("filesystem:", "file:"); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java index b789a4ed7976..cd85b0ede8a1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -67,7 +67,7 @@ public static class Registration { /** * Remote SAML Identity Provider. */ - private final AssertingParty assertingParty = new AssertingParty(); + private final Identityprovider identityprovider = new Identityprovider(); public String getEntityId() { return this.entityId; @@ -89,8 +89,8 @@ public Decryption getDecryption() { return this.decryption; } - public AssertingParty getAssertingParty() { - return this.assertingParty; + public Identityprovider getIdentityprovider() { + return this.identityprovider; } public static class Acs { @@ -224,7 +224,7 @@ public void setCertificateLocation(Resource certificate) { /** * Represents a remote Identity Provider. */ - public static class AssertingParty { + public static class Identityprovider { /** * Unique identifier for the identity provider. diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java index fa54027b3ac8..f795bae223c5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -26,9 +26,8 @@ import java.util.stream.Collectors; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.AssertingParty; -import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.AssertingParty.Verification; import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.Decryption; +import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.Identityprovider.Verification; import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.Registration; import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.Registration.Signing; import org.springframework.boot.context.properties.PropertyMapper; @@ -72,19 +71,19 @@ private RelyingPartyRegistration asRegistration(Map.Entry } private RelyingPartyRegistration asRegistration(String id, Registration properties) { - boolean usingMetadata = StringUtils.hasText(properties.getAssertingParty().getMetadataUri()); + boolean usingMetadata = StringUtils.hasText(properties.getIdentityprovider().getMetadataUri()); Builder builder = (usingMetadata) ? RelyingPartyRegistrations - .fromMetadataLocation(properties.getAssertingParty().getMetadataUri()).registrationId(id) + .fromMetadataLocation(properties.getIdentityprovider().getMetadataUri()).registrationId(id) : RelyingPartyRegistration.withRegistrationId(id); builder.assertionConsumerServiceLocation(properties.getAcs().getLocation()); builder.assertionConsumerServiceBinding(properties.getAcs().getBinding()); - builder.assertingPartyDetails(mapAssertingParty(properties.getAssertingParty(), usingMetadata)); + builder.assertingPartyDetails(mapIdentityProvider(properties, usingMetadata)); builder.signingX509Credentials((credentials) -> properties.getSigning().getCredentials().stream() .map(this::asSigningCredential).forEach(credentials::add)); builder.decryptionX509Credentials((credentials) -> properties.getDecryption().getCredentials().stream() .map(this::asDecryptionCredential).forEach(credentials::add)); builder.assertingPartyDetails((details) -> details - .verificationX509Credentials((credentials) -> properties.getAssertingParty().getVerification() + .verificationX509Credentials((credentials) -> properties.getIdentityprovider().getVerification() .getCredentials().stream().map(this::asVerificationCredential).forEach(credentials::add))); builder.entityId(properties.getEntityId()); RelyingPartyRegistration registration = builder.build(); @@ -93,14 +92,16 @@ private RelyingPartyRegistration asRegistration(String id, Registration properti return registration; } - private Consumer mapAssertingParty(AssertingParty assertingParty, + private Consumer mapIdentityProvider(Registration properties, boolean usingMetadata) { PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + Saml2RelyingPartyProperties.Identityprovider identityprovider = properties.getIdentityprovider(); return (details) -> { - map.from(assertingParty::getEntityId).to(details::entityId); - map.from(assertingParty.getSinglesignon()::getBinding).to(details::singleSignOnServiceBinding); - map.from(assertingParty.getSinglesignon()::getUrl).to(details::singleSignOnServiceLocation); - map.from(assertingParty.getSinglesignon()::isSignRequest).when((signRequest) -> !usingMetadata) + map.from(identityprovider::getEntityId).to(details::entityId); + map.from(identityprovider.getSinglesignon()::getBinding).whenNonNull() + .to(details::singleSignOnServiceBinding); + map.from(identityprovider.getSinglesignon()::getUrl).to(details::singleSignOnServiceLocation); + map.from(identityprovider.getSinglesignon()::isSignRequest).when((signRequest) -> !usingMetadata) .to(details::wantAuthnRequestsSigned); }; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionConfiguration.java index 79e011594446..e31c794c8587 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2020 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. @@ -33,7 +33,7 @@ import org.springframework.session.data.redis.RedisIndexedSessionRepository; import org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction; import org.springframework.session.data.redis.config.ConfigureRedisAction; -import org.springframework.session.data.redis.config.annotation.web.http.RedisIndexedHttpSessionConfiguration; +import org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration; /** * Redis backed session configuration. @@ -66,7 +66,7 @@ ConfigureRedisAction configureRedisAction(RedisSessionProperties redisSessionPro } @Configuration(proxyBeanMethods = false) - public static class SpringBootRedisHttpSessionConfiguration extends RedisIndexedHttpSessionConfiguration { + public static class SpringBootRedisHttpSessionConfiguration extends RedisHttpSessionConfiguration { @Autowired public void customize(SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties, diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/AbstractErrorWebExceptionHandler.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/AbstractErrorWebExceptionHandler.java index 5fd010af20c0..5bb9fd55db43 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/AbstractErrorWebExceptionHandler.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/AbstractErrorWebExceptionHandler.java @@ -320,7 +320,7 @@ protected void logError(ServerRequest request, ServerResponse response, Throwabl if (logger.isDebugEnabled()) { logger.debug(request.exchange().getLogPrefix() + formatError(throwable, request)); } - if (HttpStatus.resolve(response.statusCode().value()) != null + if (HttpStatus.resolve(response.rawStatusCode()) != null && response.statusCode().equals(HttpStatus.INTERNAL_SERVER_ERROR)) { logger.error(LogMessage.of(() -> String.format("%s 500 Server Error for %s", request.exchange().getLogPrefix(), formatRequest(request))), throwable); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 4a8659962fca..ee3ae9335351 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -243,22 +243,6 @@ "name": "server.ssl.trust-store-type", "description": "Type of the trust store." }, - { - "name": "server.ssl.certificate", - "description": "Path to a PEM-encoded SSL certificate file." - }, - { - "name": "server.ssl.certificate-private-key", - "description": "Path to a PEM-encoded private key file for the SSL certificate." - }, - { - "name": "server.ssl.trust-certificate", - "description": "Path to a PEM-encoded SSL certificate authority file." - }, - { - "name": "server.ssl.trust-certificate-private-key", - "description": "Path to a PEM-encoded private key file for the SSL certificate authority." - }, { "name": "server.tomcat.max-http-post-size", "type": "org.springframework.util.unit.DataSize", @@ -808,41 +792,6 @@ "defaultValue": "default" }, { - "name" : "spring.datasource.continue-on-error", - "type" : "java.lang.Boolean", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.continue-on-error" - } - }, { - "name" : "spring.datasource.data", - "type" : "java.util.List", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.data-locations" - } - }, { - "name" : "spring.datasource.data-password", - "type" : "java.lang.String", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.password" - } - }, { - "name" : "spring.datasource.data-username", - "type" : "java.lang.String", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.username" - } - }, { - "name" : "spring.datasource.initialization-mode", - "type" : "org.springframework.boot.jdbc.DataSourceInitializationMode", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.mode" - } - }, { "name": "spring.datasource.jmx-enabled", "type": "java.lang.Boolean", "description": "Whether to enable JMX support (if provided by the underlying pool).", @@ -851,49 +800,8 @@ "level": "error", "replacement": "spring.datasource.tomcat.jmx-enabled" } - }, { - "name" : "spring.datasource.platform", - "type" : "java.lang.String", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.platform" - } - }, { - "name" : "spring.datasource.schema", - "type" : "java.util.List", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.schema-locations" - } - }, { - "name" : "spring.datasource.schema-password", - "type" : "java.lang.String", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.password" - } - }, { - "name" : "spring.datasource.schema-username", - "type" : "java.lang.String", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.username" - } - }, { - "name" : "spring.datasource.separator", - "type" : "java.lang.String", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.separator" - } - }, { - "name" : "spring.datasource.sql-script-encoding", - "type" : "java.nio.charset.Charset", - "deprecation" : { - "level" : "error", - "replacement": "spring.sql.init.encoding" - } - }, { + }, + { "name": "spring.elasticsearch.jest.connection-timeout", "type": "java.time.Duration", "description": "Connection timeout.", diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzerTests.java index 8c241c7178d3..7dfa8484ba7b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/diagnostics/analyzer/NoSuchBeanDefinitionFailureAnalyzerTests.java @@ -46,14 +46,10 @@ * Tests for {@link NoSuchBeanDefinitionFailureAnalyzer}. * * @author Stephane Nicoll - * @author Scott Frederick */ class NoSuchBeanDefinitionFailureAnalyzerTests { - private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - - private final NoSuchBeanDefinitionFailureAnalyzer analyzer = new NoSuchBeanDefinitionFailureAnalyzer( - this.context.getBeanFactory()); + private final NoSuchBeanDefinitionFailureAnalyzer analyzer = new NoSuchBeanDefinitionFailureAnalyzer(); @Test void failureAnalysisForMultipleBeans() { @@ -212,10 +208,11 @@ private static void addExclusions(NoSuchBeanDefinitionFailureAnalyzer analyzer, } private FatalBeanException createFailure(Class config, String... environment) { - try { - TestPropertyValues.of(environment).applyTo(this.context); - this.context.register(config); - this.context.refresh(); + try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) { + this.analyzer.setBeanFactory(context.getBeanFactory()); + TestPropertyValues.of(environment).applyTo(context); + context.register(config); + context.refresh(); return null; } catch (FatalBeanException ex) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java index e979c4d1d823..24be99bfdc6b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java @@ -16,19 +16,13 @@ package org.springframework.boot.autoconfigure.elasticsearch; -import java.io.InputStream; import java.time.Duration; import java.util.HashMap; import java.util.Map; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.index.IndexRequest; -import org.elasticsearch.client.Request; import org.elasticsearch.client.RequestOptions; -import org.elasticsearch.client.Response; -import org.elasticsearch.client.RestClient; import org.junit.jupiter.api.Test; import org.testcontainers.elasticsearch.ElasticsearchContainer; import org.testcontainers.junit.jupiter.Container; @@ -46,7 +40,6 @@ * @author Brian Clozel * @author Vedran Pavic * @author Evgeniy Cheban - * @author Filip Hrisafov */ @Testcontainers(disabledWithoutDocker = true) class ElasticsearchRestClientAutoConfigurationIntegrationTests { @@ -60,7 +53,7 @@ class ElasticsearchRestClientAutoConfigurationIntegrationTests { @Test @SuppressWarnings("deprecation") - void restHighLevelClientCanQueryElasticsearchNode() { + void restClientCanQueryElasticsearchNode() { this.contextRunner .withPropertyValues("spring.elasticsearch.uris=" + elasticsearch.getHttpHostAddress(), "spring.elasticsearch.connection-timeout=120s", "spring.elasticsearch.socket-timeout=120s") @@ -77,23 +70,4 @@ void restHighLevelClientCanQueryElasticsearchNode() { }); } - @Test - void restClientCanQueryElasticsearchNode() { - this.contextRunner - .withPropertyValues("spring.elasticsearch.uris=" + elasticsearch.getHttpHostAddress(), - "spring.elasticsearch.connection-timeout=120s", "spring.elasticsearch.socket-timeout=120s") - .run((context) -> { - RestClient client = context.getBean(RestClient.class); - Request index = new Request("PUT", "/test/_doc/2"); - index.setJsonEntity("{" + " \"a\": \"alpha\"," + " \"b\": \"bravo\"" + "}"); - client.performRequest(index); - Request getRequest = new Request("GET", "/test/_doc/2"); - Response response = client.performRequest(getRequest); - try (InputStream input = response.getEntity().getContent()) { - JsonNode result = new ObjectMapper().readTree(input); - assertThat(result.path("found").asBoolean()).isTrue(); - } - }); - } - } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationTests.java index 3a8f1723a07c..d92bd99a1135 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationTests.java @@ -17,6 +17,7 @@ package org.springframework.boot.autoconfigure.elasticsearch; import java.time.Duration; +import java.util.Map; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; @@ -48,7 +49,6 @@ * @author Vedran Pavic * @author Evgeniy Cheban * @author Filip Hrisafov - * @author Andy Wilkinson */ @SuppressWarnings("deprecation") class ElasticsearchRestClientAutoConfigurationTests { @@ -57,22 +57,19 @@ class ElasticsearchRestClientAutoConfigurationTests { .withConfiguration(AutoConfigurations.of(ElasticsearchRestClientAutoConfiguration.class)); @Test - void configureShouldCreateHighLevelAndLowLevelRestClients() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(RestClient.class) - .hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class) - .hasSingleBean(RestClientBuilder.class); - assertThat(context.getBean(RestClient.class)) - .isEqualTo(context.getBean(org.elasticsearch.client.RestHighLevelClient.class).getLowLevelClient()); - }); + void configureShouldOnlyCreateHighLevelRestClient() { + this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(RestClient.class) + .hasSingleBean(RestClientBuilder.class) + .hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class)); + } @Test - void configureWithoutRestHighLevelClientShouldOnlyCreateRestClientBuilderAndRestClient() { + void configureWithoutRestHighLevelClientShouldOnlyCreateRestClientBuilder() { this.contextRunner.withClassLoader(new FilteredClassLoader(org.elasticsearch.client.RestHighLevelClient.class)) - .run((context) -> assertThat(context).hasSingleBean(RestClient.class) - .hasSingleBean(RestClientBuilder.class) - .doesNotHaveBean(org.elasticsearch.client.RestHighLevelClient.class)); + .run((context) -> assertThat(context).doesNotHaveBean(RestClient.class) + .doesNotHaveBean(org.elasticsearch.client.RestHighLevelClient.class) + .hasSingleBean(RestClientBuilder.class)); } @Test @@ -85,33 +82,24 @@ void configureWhenCustomRestClientShouldBackOff() { } @Test - void configureWhenCustomRestHighLevelClientShouldDefineRestClientFromCustomHighLevelClient() { - this.contextRunner.withUserConfiguration(CustomRestHighLevelClientConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class) - .hasSingleBean(RestClient.class).hasBean("elasticsearchRestClient").getBean(RestClient.class) - .isEqualTo(context.getBean(org.elasticsearch.client.RestHighLevelClient.class) - .getLowLevelClient())); - } - - @Test - void configureWhenCustomRestHighLevelClientAndRestClientShouldBackOff() { - this.contextRunner.withUserConfiguration(CustomRestHighLevelClientWithRestClientConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class) - .hasBean("customRestHighLevelClient").hasSingleBean(RestClient.class) - .hasBean("customRestClient")); + void configureWhenCustomRestHighLevelClientShouldBackOff() { + this.contextRunner.withUserConfiguration(CustomRestHighLevelClientConfiguration.class).run( + (context) -> assertThat(context).hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class)); } @Test - void configureWhenNoUniqueRestHighLevelClientShouldNotDefineRestClient() { - this.contextRunner.withUserConfiguration(TwoCustomRestHighLevelClientsConfiguration.class) - .run((context) -> assertThat(context).doesNotHaveBean(RestClient.class)); + void configureWhenDefaultRestClientShouldCreateWhenNoUniqueRestHighLevelClient() { + this.contextRunner.withUserConfiguration(TwoCustomRestHighLevelClientConfiguration.class).run((context) -> { + Map restHighLevelClients = context + .getBeansOfType(org.elasticsearch.client.RestHighLevelClient.class); + assertThat(restHighLevelClients).hasSize(2); + }); } @Test void configureWhenBuilderCustomizerShouldApply() { this.contextRunner.withUserConfiguration(BuilderCustomizerConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class) - .hasSingleBean(RestClient.class); + assertThat(context).hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class); org.elasticsearch.client.RestHighLevelClient restClient = context .getBean(org.elasticsearch.client.RestHighLevelClient.class); RestClient lowLevelClient = restClient.getLowLevelClient(); @@ -124,8 +112,9 @@ void configureWhenBuilderCustomizerShouldApply() { @Test void configureWithNoTimeoutsApplyDefaults() { this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(RestClient.class); - RestClient restClient = context.getBean(RestClient.class); + assertThat(context).hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class); + org.elasticsearch.client.RestHighLevelClient restClient = context + .getBean(org.elasticsearch.client.RestHighLevelClient.class); assertTimeouts(restClient, Duration.ofMillis(RestClientBuilder.DEFAULT_CONNECT_TIMEOUT_MILLIS), Duration.ofMillis(RestClientBuilder.DEFAULT_SOCKET_TIMEOUT_MILLIS)); }); @@ -135,23 +124,25 @@ void configureWithNoTimeoutsApplyDefaults() { void configureWithCustomTimeouts() { this.contextRunner.withPropertyValues("spring.elasticsearch.connection-timeout=15s", "spring.elasticsearch.socket-timeout=1m").run((context) -> { - assertThat(context).hasSingleBean(RestClient.class); - RestClient restClient = context.getBean(RestClient.class); + assertThat(context).hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class); + org.elasticsearch.client.RestHighLevelClient restClient = context + .getBean(org.elasticsearch.client.RestHighLevelClient.class); assertTimeouts(restClient, Duration.ofSeconds(15), Duration.ofMinutes(1)); }); } - private static void assertTimeouts(RestClient restClient, Duration connectTimeout, Duration readTimeout) { - assertThat(restClient).extracting("client.defaultConfig.socketTimeout") + private static void assertTimeouts(org.elasticsearch.client.RestHighLevelClient restClient, Duration connectTimeout, + Duration readTimeout) { + assertThat(restClient.getLowLevelClient()).extracting("client.defaultConfig.socketTimeout") .isEqualTo(Math.toIntExact(readTimeout.toMillis())); - assertThat(restClient).extracting("client.defaultConfig.connectTimeout") + assertThat(restClient.getLowLevelClient()).extracting("client.defaultConfig.connectTimeout") .isEqualTo(Math.toIntExact(connectTimeout.toMillis())); } @Test void configureUriWithNoScheme() { this.contextRunner.withPropertyValues("spring.elasticsearch.uris=localhost:9876").run((context) -> { - RestClient client = context.getBean(RestClient.class); + RestClient client = context.getBean(org.elasticsearch.client.RestHighLevelClient.class).getLowLevelClient(); assertThat(client.getNodes().stream().map(Node::getHost).map(HttpHost::toString)) .containsExactly("http://localhost:9876"); }); @@ -160,7 +151,7 @@ void configureUriWithNoScheme() { @Test void configureUriWithUsernameOnly() { this.contextRunner.withPropertyValues("spring.elasticsearch.uris=http://user@localhost:9200").run((context) -> { - RestClient client = context.getBean(RestClient.class); + RestClient client = context.getBean(org.elasticsearch.client.RestHighLevelClient.class).getLowLevelClient(); assertThat(client.getNodes().stream().map(Node::getHost).map(HttpHost::toString)) .containsExactly("http://localhost:9200"); assertThat(client) @@ -177,7 +168,8 @@ void configureUriWithUsernameOnly() { void configureUriWithUsernameAndEmptyPassword() { this.contextRunner.withPropertyValues("spring.elasticsearch.uris=http://user:@localhost:9200") .run((context) -> { - RestClient client = context.getBean(RestClient.class); + RestClient client = context.getBean(org.elasticsearch.client.RestHighLevelClient.class) + .getLowLevelClient(); assertThat(client.getNodes().stream().map(Node::getHost).map(HttpHost::toString)) .containsExactly("http://localhost:9200"); assertThat(client) @@ -198,7 +190,8 @@ void configureUriWithUsernameAndPasswordWhenUsernameAndPasswordPropertiesSet() { .withPropertyValues("spring.elasticsearch.uris=http://user:password@localhost:9200,localhost:9201", "spring.elasticsearch.username=admin", "spring.elasticsearch.password=admin") .run((context) -> { - RestClient client = context.getBean(RestClient.class); + RestClient client = context.getBean(org.elasticsearch.client.RestHighLevelClient.class) + .getLowLevelClient(); assertThat(client.getNodes().stream().map(Node::getHost).map(HttpHost::toString)) .containsExactly("http://localhost:9200", "http://localhost:9201"); assertThat(client) @@ -220,7 +213,7 @@ void configureUriWithUsernameAndPasswordWhenUsernameAndPasswordPropertiesSet() { @Test void configureWithCustomPathPrefix() { this.contextRunner.withPropertyValues("spring.elasticsearch.path-prefix=/some/prefix").run((context) -> { - RestClient client = context.getBean(RestClient.class); + RestClient client = context.getBean(org.elasticsearch.client.RestHighLevelClient.class).getLowLevelClient(); assertThat(client).extracting("pathPrefix").isEqualTo("/some/prefix"); }); } @@ -229,21 +222,19 @@ void configureWithCustomPathPrefix() { void configureWithoutSnifferLibraryShouldNotCreateSniffer() { this.contextRunner.withClassLoader(new FilteredClassLoader("org.elasticsearch.client.sniff")) .run((context) -> assertThat(context).hasSingleBean(org.elasticsearch.client.RestHighLevelClient.class) - .hasSingleBean(RestClient.class).doesNotHaveBean(Sniffer.class)); + .doesNotHaveBean(Sniffer.class)); } @Test - void configureShouldCreateSnifferUsingRestClient() { - this.contextRunner.withClassLoader(new FilteredClassLoader(org.elasticsearch.client.RestHighLevelClient.class)) - .run((context) -> { - assertThat(context).hasSingleBean(Sniffer.class); - assertThat(context.getBean(Sniffer.class)).hasFieldOrPropertyWithValue("restClient", - context.getBean(RestClient.class)); - // Validate shutdown order as the sniffer must be shutdown before the - // client - assertThat(context.getBeanFactory().getDependentBeans("elasticsearchRestClient")) - .contains("elasticsearchSniffer"); - }); + void configureShouldCreateSnifferUsingRestHighLevelClient() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(Sniffer.class); + assertThat(context.getBean(Sniffer.class)).hasFieldOrPropertyWithValue("restClient", + context.getBean(org.elasticsearch.client.RestHighLevelClient.class).getLowLevelClient()); + // Validate shutdown order as the sniffer must be shutdown before the client + assertThat(context.getBeanFactory().getDependentBeans("elasticsearchRestHighLevelClient")) + .contains("elasticsearchSniffer"); + }); } @Test @@ -308,7 +299,7 @@ org.elasticsearch.client.RestHighLevelClient customRestHighLevelClient(RestClien } @Configuration(proxyBeanMethods = false) - static class CustomRestHighLevelClientWithRestClientConfiguration { + static class TwoCustomRestHighLevelClientConfiguration { @Bean org.elasticsearch.client.RestHighLevelClient customRestHighLevelClient(RestClientBuilder builder) { @@ -316,22 +307,7 @@ org.elasticsearch.client.RestHighLevelClient customRestHighLevelClient(RestClien } @Bean - RestClient customRestClient(org.elasticsearch.client.RestHighLevelClient restHighLevelClient) { - return restHighLevelClient.getLowLevelClient(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TwoCustomRestHighLevelClientsConfiguration { - - @Bean - org.elasticsearch.client.RestHighLevelClient customRestHighLevelClient(RestClientBuilder builder) { - return new org.elasticsearch.client.RestHighLevelClient(builder); - } - - @Bean - org.elasticsearch.client.RestHighLevelClient anotherCustomRestHighLevelClient(RestClientBuilder builder) { + org.elasticsearch.client.RestHighLevelClient customoRestHighLevelClient1(RestClientBuilder builder) { return new org.elasticsearch.client.RestHighLevelClient(builder); } @@ -347,19 +323,4 @@ RestClient customRestClient(RestClientBuilder builder) { } - @Configuration(proxyBeanMethods = false) - static class TwoCustomRestClientConfiguration { - - @Bean - RestClient customRestClient(RestClientBuilder builder) { - return builder.build(); - } - - @Bean - RestClient customRestClient1(RestClientBuilder builder) { - return builder.build(); - } - - } - } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/gson/GsonAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/gson/GsonAutoConfigurationTests.java index 6e1f0e0aa5f6..772f36879ebb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/gson/GsonAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/gson/GsonAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -29,7 +29,6 @@ import com.google.gson.GsonBuilder; import com.google.gson.LongSerializationPolicy; import org.junit.jupiter.api.Test; -import org.skyscreamer.jsonassert.JSONAssert; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -151,7 +150,7 @@ void additionalGsonBuilderCustomization() { void customGsonBuilder() { this.contextRunner.withUserConfiguration(GsonBuilderConfig.class).run((context) -> { Gson gson = context.getBean(Gson.class); - JSONAssert.assertEquals("{\"data\":1,\"owner\":null}", gson.toJson(new DataObject()), true); + assertThat(gson.toJson(new DataObject())).isEqualTo("{\"data\":1,\"owner\":null}"); }); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java index 73d7a39cc8c4..fb4f3880cf68 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -17,7 +17,6 @@ package org.springframework.boot.autoconfigure.security.oauth2.resource.reactive; import java.io.IOException; -import java.time.Duration; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -84,8 +83,6 @@ class ReactiveOAuth2ResourceServerAutoConfigurationTests { private MockWebServer server; - private static final Duration TIMEOUT = Duration.ofSeconds(5); - private static final String JWK_SET = "{\"keys\":[{\"kty\":\"RSA\",\"e\":\"AQAB\",\"use\":\"sig\"," + "\"kid\":\"one\",\"n\":\"oXJ8OyOv_eRnce4akdanR4KYRfnC2zLV4uYNQpcFn6oHL0dj7D6kxQmsXoYgJV8ZVDn71KGm" + "uLvolxsDncc2UrhyMBY6DVQVgMSVYaPCTgW76iYEKGgzTEw5IBRQL9w3SRJWd3VJTZZQjkXef48Ocz06PGF3lhbz4t5UEZtd" @@ -151,7 +148,7 @@ void autoConfigurationShouldConfigureResourceServerUsingOidcIssuerUri() throws I .getBean(SupplierReactiveJwtDecoder.class); Mono reactiveJwtDecoderSupplier = (Mono) ReflectionTestUtils .getField(supplierReactiveJwtDecoder, "jwtDecoderMono"); - ReactiveJwtDecoder reactiveJwtDecoder = reactiveJwtDecoderSupplier.block(TIMEOUT); + ReactiveJwtDecoder reactiveJwtDecoder = reactiveJwtDecoderSupplier.block(); }); // The last request is to the JWK Set endpoint to look up the algorithm assertThat(this.server.getRequestCount()).isEqualTo(1); @@ -174,7 +171,7 @@ void autoConfigurationShouldConfigureResourceServerUsingOidcRfc8414IssuerUri() t .getBean(SupplierReactiveJwtDecoder.class); Mono reactiveJwtDecoderSupplier = (Mono) ReflectionTestUtils .getField(supplierReactiveJwtDecoder, "jwtDecoderMono"); - ReactiveJwtDecoder reactiveJwtDecoder = reactiveJwtDecoderSupplier.block(TIMEOUT); + ReactiveJwtDecoder reactiveJwtDecoder = reactiveJwtDecoderSupplier.block(); }); // The last request is to the JWK Set endpoint to look up the algorithm assertThat(this.server.getRequestCount()).isEqualTo(2); @@ -197,7 +194,7 @@ void autoConfigurationShouldConfigureResourceServerUsingOAuthIssuerUri() throws .getBean(SupplierReactiveJwtDecoder.class); Mono reactiveJwtDecoderSupplier = (Mono) ReflectionTestUtils .getField(supplierReactiveJwtDecoder, "jwtDecoderMono"); - ReactiveJwtDecoder reactiveJwtDecoder = reactiveJwtDecoderSupplier.block(TIMEOUT); + ReactiveJwtDecoder reactiveJwtDecoder = reactiveJwtDecoderSupplier.block(); }); // The last request is to the JWK Set endpoint to look up the algorithm assertThat(this.server.getRequestCount()).isEqualTo(3); @@ -398,7 +395,7 @@ private void assertFilterConfiguredWithJwtAuthenticationManager(AssertableReacti .filter((f) -> f instanceof AuthenticationWebFilter).findFirst().orElse(null); ReactiveAuthenticationManagerResolver authenticationManagerResolver = (ReactiveAuthenticationManagerResolver) ReflectionTestUtils .getField(webFilter, "authenticationManagerResolver"); - Object authenticationManager = authenticationManagerResolver.resolve(null).block(TIMEOUT); + Object authenticationManager = authenticationManagerResolver.resolve(null).block(); assertThat(authenticationManager).isInstanceOf(JwtReactiveAuthenticationManager.class); } @@ -411,7 +408,7 @@ private void assertFilterConfiguredWithOpaqueTokenAuthenticationManager( .filter((f) -> f instanceof AuthenticationWebFilter).findFirst().orElse(null); ReactiveAuthenticationManagerResolver authenticationManagerResolver = (ReactiveAuthenticationManagerResolver) ReflectionTestUtils .getField(webFilter, "authenticationManagerResolver"); - Object authenticationManager = authenticationManagerResolver.resolve(null).block(TIMEOUT); + Object authenticationManager = authenticationManagerResolver.resolve(null).block(); assertThat(authenticationManager).isInstanceOf(OpaqueTokenReactiveAuthenticationManager.class); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java index 81d92c4bd03b..b38f8fb64c67 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java @@ -120,12 +120,12 @@ void autoConfigurationWhenSignRequestsFalseAndNoSigningCredentialsShouldNotThrow } @Test - void autoconfigurationShouldQueryAssertingPartyMetadataWhenMetadataUrlIsPresent() throws Exception { + void autoconfigurationShouldQueryIdentityProviderMetadataWhenMetadataUrlIsPresent() throws Exception { try (MockWebServer server = new MockWebServer()) { server.start(); String metadataUrl = server.url("").toString(); setupMockResponse(server, new ClassPathResource("saml/idp-metadata")); - this.contextRunner.withPropertyValues(PREFIX + ".foo.asserting-party.metadata-uri=" + metadataUrl) + this.contextRunner.withPropertyValues(PREFIX + ".foo.identityprovider.metadata-uri=" + metadataUrl) .run((context) -> { assertThat(context).hasSingleBean(RelyingPartyRegistrationRepository.class); assertThat(server.getRequestCount()).isEqualTo(1); @@ -139,7 +139,7 @@ void autoconfigurationShouldUseBindingFromMetadataUrlIfPresent() throws Exceptio server.start(); String metadataUrl = server.url("").toString(); setupMockResponse(server, new ClassPathResource("saml/idp-metadata")); - this.contextRunner.withPropertyValues(PREFIX + ".foo.asserting-party.metadata-uri=" + metadataUrl) + this.contextRunner.withPropertyValues(PREFIX + ".foo.identityprovider.metadata-uri=" + metadataUrl) .run((context) -> { RelyingPartyRegistrationRepository repository = context .getBean(RelyingPartyRegistrationRepository.class); @@ -156,8 +156,8 @@ void autoconfigurationWhenMetadataUrlAndPropertyPresentShouldUseBindingFromPrope server.start(); String metadataUrl = server.url("").toString(); setupMockResponse(server, new ClassPathResource("saml/idp-metadata")); - this.contextRunner.withPropertyValues(PREFIX + ".foo.asserting-party.metadata-uri=" + metadataUrl, - PREFIX + ".foo.asserting-party.singlesignon.binding=redirect").run((context) -> { + this.contextRunner.withPropertyValues(PREFIX + ".foo.identityprovider.metadata-uri=" + metadataUrl, + PREFIX + ".foo.identityprovider.singlesignon.binding=redirect").run((context) -> { RelyingPartyRegistrationRepository repository = context .getBean(RelyingPartyRegistrationRepository.class); RelyingPartyRegistration registration = repository.findByRegistrationId("foo"); @@ -215,19 +215,19 @@ void samlLoginShouldShouldBeConditionalOnSecurityWebFilterClass() { private String[] getPropertyValuesWithoutSigningCredentials(boolean signRequests) { return new String[] { PREFIX - + ".foo.asserting-party.singlesignon.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php", - PREFIX + ".foo.asserting-party.singlesignon.binding=post", - PREFIX + ".foo.asserting-party.singlesignon.sign-request=" + signRequests, - PREFIX + ".foo.asserting-party.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", - PREFIX + ".foo.asserting-party.verification.credentials[0].certificate-location=classpath:saml/certificate-location" }; + + ".foo.identityprovider.singlesignon.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php", + PREFIX + ".foo.identityprovider.singlesignon.binding=post", + PREFIX + ".foo.identityprovider.singlesignon.sign-request=" + signRequests, + PREFIX + ".foo.identityprovider.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", + PREFIX + ".foo.identityprovider.verification.credentials[0].certificate-location=classpath:saml/certificate-location" }; } private String[] getPropertyValuesWithoutSsoBinding() { return new String[] { PREFIX - + ".foo.asserting-party.singlesignon.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php", - PREFIX + ".foo.asserting-party.singlesignon.sign-request=false", - PREFIX + ".foo.asserting-party.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", - PREFIX + ".foo.asserting-party.verification.credentials[0].certificate-location=classpath:saml/certificate-location" }; + + ".foo.identityprovider.singlesignon.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php", + PREFIX + ".foo.identityprovider.singlesignon.sign-request=false", + PREFIX + ".foo.identityprovider.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", + PREFIX + ".foo.identityprovider.verification.credentials[0].certificate-location=classpath:saml/certificate-location" }; } private String[] getPropertyValues() { @@ -236,11 +236,11 @@ private String[] getPropertyValues() { PREFIX + ".foo.signing.credentials[0].certificate-location=classpath:saml/certificate-location", PREFIX + ".foo.decryption.credentials[0].private-key-location=classpath:saml/private-key-location", PREFIX + ".foo.decryption.credentials[0].certificate-location=classpath:saml/certificate-location", - PREFIX + ".foo.asserting-party.singlesignon.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php", - PREFIX + ".foo.asserting-party.singlesignon.binding=post", - PREFIX + ".foo.asserting-party.singlesignon.sign-request=false", - PREFIX + ".foo.asserting-party.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", - PREFIX + ".foo.asserting-party.verification.credentials[0].certificate-location=classpath:saml/certificate-location", + PREFIX + ".foo.identityprovider.singlesignon.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php", + PREFIX + ".foo.identityprovider.singlesignon.binding=post", + PREFIX + ".foo.identityprovider.singlesignon.sign-request=false", + PREFIX + ".foo.identityprovider.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php", + PREFIX + ".foo.identityprovider.verification.credentials[0].certificate-location=classpath:saml/certificate-location", PREFIX + ".foo.entity-id={baseUrl}/saml2/foo-entity-id", PREFIX + ".foo.acs.location={baseUrl}/login/saml2/foo-entity-id", PREFIX + ".foo.acs.binding=redirect" }; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java index 9dd726543895..04f16e9f9618 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -41,29 +41,36 @@ class Saml2RelyingPartyPropertiesTests { @Test void customizeSsoUrl() { - bind("spring.security.saml2.relyingparty.registration.simplesamlphp.asserting-party.single-sign-on.url", + bind("spring.security.saml2.relyingparty.registration.simplesamlphp.identity-provider.single-sign-on.url", "https://simplesaml-for-spring-saml/SSOService.php"); assertThat( - this.properties.getRegistration().get("simplesamlphp").getAssertingParty().getSinglesignon().getUrl()) + this.properties.getRegistration().get("simplesamlphp").getIdentityprovider().getSinglesignon().getUrl()) .isEqualTo("https://simplesaml-for-spring-saml/SSOService.php"); } @Test void customizeSsoBinding() { - bind("spring.security.saml2.relyingparty.registration.simplesamlphp.asserting-party.single-sign-on.binding", + bind("spring.security.saml2.relyingparty.registration.simplesamlphp.identity-provider.single-sign-on.binding", "post"); - assertThat(this.properties.getRegistration().get("simplesamlphp").getAssertingParty().getSinglesignon() + assertThat(this.properties.getRegistration().get("simplesamlphp").getIdentityprovider().getSinglesignon() .getBinding()).isEqualTo(Saml2MessageBinding.POST); } @Test void customizeSsoSignRequests() { - bind("spring.security.saml2.relyingparty.registration.simplesamlphp.asserting-party.single-sign-on.sign-request", + bind("spring.security.saml2.relyingparty.registration.simplesamlphp.identity-provider.single-sign-on.sign-request", "false"); - assertThat(this.properties.getRegistration().get("simplesamlphp").getAssertingParty().getSinglesignon() + assertThat(this.properties.getRegistration().get("simplesamlphp").getIdentityprovider().getSinglesignon() .isSignRequest()).isEqualTo(false); } + @Test + void customizeSsoSignRequestsIsTrueByDefault() { + this.properties.getRegistration().put("simplesamlphp", new Saml2RelyingPartyProperties.Registration()); + assertThat(this.properties.getRegistration().get("simplesamlphp").getIdentityprovider().getSinglesignon() + .isSignRequest()).isEqualTo(true); + } + @Test void customizeRelyingPartyEntityId() { bind("spring.security.saml2.relyingparty.registration.simplesamlphp.entity-id", @@ -79,20 +86,13 @@ void customizeRelyingPartyEntityIdDefaultsToServiceProviderMetadata() { } @Test - void customizeAssertingPartyMetadataUri() { - bind("spring.security.saml2.relyingparty.registration.simplesamlphp.asserting-party.metadata-uri", + void customizeIdentityProviderMetadataUri() { + bind("spring.security.saml2.relyingparty.registration.simplesamlphp.identityprovider.metadata-uri", "https://idp.example.org/metadata"); - assertThat(this.properties.getRegistration().get("simplesamlphp").getAssertingParty().getMetadataUri()) + assertThat(this.properties.getRegistration().get("simplesamlphp").getIdentityprovider().getMetadataUri()) .isEqualTo("https://idp.example.org/metadata"); } - @Test - void customizeSsoSignRequestsIsTrueByDefault() { - this.properties.getRegistration().put("simplesamlphp", new Saml2RelyingPartyProperties.Registration()); - assertThat(this.properties.getRegistration().get("simplesamlphp").getAssertingParty().getSinglesignon() - .isSignRequest()).isEqualTo(true); - } - private void bind(String name, String value) { bind(Collections.singletonMap(name, value)); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java index 8f7ef62b92bd..6e81c0217309 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java @@ -97,7 +97,8 @@ void defaultMediaTypes() { MediaType.APPLICATION_ATOM_XML, new MediaType("application", "javascript"), new MediaType("application", "ecmascript"), new MediaType("text", "javascript"), new MediaType("text", "ecmascript"), MediaType.APPLICATION_JSON, - new MediaType("text", "css"), MediaType.TEXT_PLAIN, MediaType.TEXT_EVENT_STREAM)); + new MediaType("text", "css"), MediaType.TEXT_PLAIN, MediaType.TEXT_EVENT_STREAM) + .satisfies(System.out::println)); } @Test diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientAutoConfigurationTests.java index 509effe61c37..9059dd3b0666 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientAutoConfigurationTests.java @@ -16,7 +16,12 @@ package org.springframework.boot.autoconfigure.web.reactive.function.client; +import java.net.URI; +import java.time.Duration; + import org.junit.jupiter.api.Test; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -24,13 +29,20 @@ import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.client.reactive.ClientHttpConnector; +import org.springframework.http.client.reactive.ClientHttpResponse; import org.springframework.http.codec.CodecConfigurer; import org.springframework.web.reactive.function.client.WebClient; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.then; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; /** * Tests for {@link WebClientAutoConfiguration} @@ -76,9 +88,26 @@ void webClientShouldApplyCustomizers() { @Test void shouldGetPrototypeScopedBean() { this.contextRunner.withUserConfiguration(WebClientCustomizerConfig.class).run((context) -> { + ClientHttpResponse response = mock(ClientHttpResponse.class); + given(response.getBody()).willReturn(Flux.empty()); + given(response.getHeaders()).willReturn(new HttpHeaders()); + ClientHttpConnector firstConnector = mock(ClientHttpConnector.class); + given(firstConnector.connect(any(), any(), any())).willReturn(Mono.just(response)); WebClient.Builder firstBuilder = context.getBean(WebClient.Builder.class); + firstBuilder.clientConnector(firstConnector).baseUrl("https://first.example.org"); + ClientHttpConnector secondConnector = mock(ClientHttpConnector.class); + given(secondConnector.connect(any(), any(), any())).willReturn(Mono.just(response)); WebClient.Builder secondBuilder = context.getBean(WebClient.Builder.class); + secondBuilder.clientConnector(secondConnector).baseUrl("https://second.example.org"); assertThat(firstBuilder).isNotEqualTo(secondBuilder); + firstBuilder.build().get().uri("/foo").retrieve().toBodilessEntity().block(Duration.ofSeconds(30)); + secondBuilder.build().get().uri("/foo").retrieve().toBodilessEntity().block(Duration.ofSeconds(30)); + then(firstConnector).should().connect(eq(HttpMethod.GET), eq(URI.create("https://first.example.org/foo")), + any()); + then(secondConnector).should().connect(eq(HttpMethod.GET), eq(URI.create("https://second.example.org/foo")), + any()); + WebClientCustomizer customizer = context.getBean("webClientCustomizer", WebClientCustomizer.class); + then(customizer).should(times(2)).customize(any(WebClient.Builder.class)); }); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java index 59cbd17916a3..0d3b6dff4fd6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java @@ -26,7 +26,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.http.MediaType; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/RemappedErrorViewIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/RemappedErrorViewIntegrationTests.java index b5e25e65c007..72ff200d3cf3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/RemappedErrorViewIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/RemappedErrorViewIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -27,10 +27,10 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.server.ErrorPage; import org.springframework.boot.web.server.ErrorPageRegistrar; import org.springframework.boot.web.server.ErrorPageRegistry; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.stereotype.Controller; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketMessagingAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketMessagingAutoConfigurationTests.java index 21019ab69328..7043d05f3912 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketMessagingAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketMessagingAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -30,7 +30,6 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.skyscreamer.jsonassert.JSONAssert; import org.springframework.boot.LazyInitializationBeanFactoryPostProcessor; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -39,6 +38,7 @@ import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.annotation.Bean; @@ -101,7 +101,7 @@ void tearDown() { @Test void basicMessagingWithJsonResponse() throws Throwable { Object result = performStompSubscription("/app/json"); - JSONAssert.assertEquals("{\"foo\" : 5,\"bar\" : \"baz\"}", new String((byte[]) result), true); + assertThat(new String((byte[]) result)).isEqualTo(String.format("{%n \"foo\" : 5,%n \"bar\" : \"baz\"%n}")); } @Test @@ -146,6 +146,7 @@ private List getDefaultConverters() { private Object performStompSubscription(String topic) throws Throwable { TestPropertyValues.of("server.port:0", "spring.jackson.serialization.indent-output:true").applyTo(this.context); this.context.register(WebSocketMessagingConfiguration.class); + new ServerPortInfoApplicationContextInitializer().initialize(this.context); this.context.refresh(); WebSocketStompClient stompClient = new WebSocketStompClient(this.sockJsClient); final AtomicReference failure = new AtomicReference<>(); @@ -192,7 +193,8 @@ public void handleTransportError(StompSession session, Throwable exception) { }; stompClient.setMessageConverter(new SimpleMessageConverter()); - stompClient.connect("ws://localhost:{port}/messaging", handler, this.context.getWebServer().getPort()); + stompClient.connect("ws://localhost:{port}/messaging", handler, + this.context.getEnvironment().getProperty("local.server.port")); if (!latch.await(30, TimeUnit.SECONDS)) { if (failure.get() != null) { diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 579019537e05..d4fb5389fa18 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -24,7 +24,7 @@ bom { ] } } - library("AppEngine SDK", "1.9.96") { + library("AppEngine SDK", "1.9.95") { group("com.google.appengine") { modules = [ "appengine-api-1.0-sdk" @@ -79,7 +79,7 @@ bom { ] } } - library("Byte Buddy", "1.12.9") { + library("Byte Buddy", "1.12.8") { group("net.bytebuddy") { modules = [ "byte-buddy", @@ -216,7 +216,7 @@ bom { ] } } - library("Elasticsearch", "7.17.2") { + library("Elasticsearch", "7.17.1") { group("org.elasticsearch") { modules = [ "elasticsearch" @@ -254,7 +254,7 @@ bom { ] } } - library("Flyway", "8.5.8") { + library("Flyway", "8.5.4") { group("org.flywaydb") { modules = [ "flyway-core", @@ -323,7 +323,7 @@ bom { ] } } - library("H2", "2.1.212") { + library("H2", "2.1.210") { group("com.h2database") { modules = [ "h2" @@ -355,7 +355,7 @@ bom { ] } } - library("Hibernate", "5.6.8.Final") { + library("Hibernate", "5.6.7.Final") { group("org.hibernate") { modules = [ "hibernate-c3p0", @@ -463,7 +463,7 @@ bom { ] } } - library("Jackson Bom", "2.13.2.1") { + library("Jackson Bom", "2.13.2") { group("com.fasterxml.jackson") { imports = [ "jackson-bom" @@ -795,7 +795,7 @@ bom { ] } } - library("Kotlin Coroutines", "1.6.1") { + library("Kotlin Coroutines", "1.6.0") { group("org.jetbrains.kotlinx") { imports = [ "kotlinx-coroutines-bom" @@ -809,7 +809,7 @@ bom { ] } } - library("Liquibase", "4.9.1") { + library("Liquibase", "4.9.0") { group("org.liquibase") { modules = [ "liquibase-cdi", @@ -836,14 +836,14 @@ bom { ] } } - library("Lombok", "1.18.24") { + library("Lombok", "1.18.22") { group("org.projectlombok") { modules = [ "lombok" ] } } - library("MariaDB", "3.0.4") { + library("MariaDB", "3.0.3") { group("org.mariadb.jdbc") { modules = [ "mariadb-java-client" @@ -864,7 +864,7 @@ bom { ] } } - library("Maven Clean Plugin", "3.2.0") { + library("Maven Clean Plugin", "3.1.0") { group("org.apache.maven.plugins") { plugins = [ "maven-clean-plugin" @@ -948,7 +948,7 @@ bom { ] } } - library("Maven Shade Plugin", "3.3.0") { + library("Maven Shade Plugin", "3.2.4") { group("org.apache.maven.plugins") { plugins = [ "maven-shade-plugin" @@ -976,7 +976,7 @@ bom { ] } } - library("Micrometer", "1.10.0-SNAPSHOT") { + library("Micrometer", "2.0.0-SNAPSHOT") { group("io.micrometer") { modules = [ "micrometer-registry-stackdriver" { @@ -990,26 +990,28 @@ bom { } library("Micrometer Tracing", "1.0.0-SNAPSHOT") { group("io.micrometer") { - imports = [ - "micrometer-tracing-bom" + modules = [ + "micrometer-tracing-api" ] } } - library("MIMEPull", "1.10.0") { + library("MIMEPull", "1.9.15") { group("org.jvnet.mimepull") { modules = [ "mimepull" ] } } - library("Mockito", "4.5.0") { + library("Mockito", "4.4.0") { group("org.mockito") { - imports = [ - "mockito-bom" + modules = [ + "mockito-core", + "mockito-inline", + "mockito-junit-jupiter" ] } } - library("MongoDB", "4.6.0") { + library("MongoDB", "4.5.1") { group("org.mongodb") { modules = [ "bson", @@ -1050,7 +1052,7 @@ bom { ] } } - library("Netty", "4.1.76.Final") { + library("Netty", "4.1.75.Final") { group("io.netty") { imports = [ "netty-bom" @@ -1072,13 +1074,6 @@ bom { ] } } - library("OpenTelemetry", "1.12.0") { - group("io.opentelemetry") { - imports = [ - "opentelemetry-bom" - ] - } - } library("Oracle Database", "21.5.0.0") { group("com.oracle.database.jdbc") { imports = [ @@ -1146,7 +1141,7 @@ bom { ] } } - library("Reactor Bom", "2020.0.18") { + library("Reactor Bom", "2020.0.17") { group("io.projectreactor") { imports = [ "reactor-bom" @@ -1166,7 +1161,7 @@ bom { ] } } - library("RSocket", "1.1.2") { + library("RSocket", "1.1.1") { group("io.rsocket") { imports = [ "rsocket-bom" @@ -1364,21 +1359,21 @@ bom { ] } } - library("Spring Data Bom", "2022.0.0-SNAPSHOT") { + library("Spring Data Bom", "2022.0.0-M3") { group("org.springframework.data") { imports = [ "spring-data-bom" ] } } - library("Spring Framework", "6.0.0-SNAPSHOT") { + library("Spring Framework", "6.0.0-M3") { group("org.springframework") { imports = [ "spring-framework-bom" ] } } - library("Spring HATEOAS", "2.0.0-SNAPSHOT") { + library("Spring HATEOAS", "2.0.0-M2") { group("org.springframework.hateoas") { modules = [ "spring-hateoas" @@ -1392,7 +1387,7 @@ bom { ] } } - library("Spring Kafka", "3.0.0-SNAPSHOT") { + library("Spring Kafka", "3.0.0-M3") { group("org.springframework.kafka") { modules = [ "spring-kafka", @@ -1423,21 +1418,21 @@ bom { ] } } - library("Spring Retry", "1.3.3") { + library("Spring Retry", "1.3.2") { group("org.springframework.retry") { modules = [ "spring-retry" ] } } - library("Spring Security", "6.0.0-SNAPSHOT") { + library("Spring Security", "6.0.0-M3") { group("org.springframework.security") { imports = [ "spring-security-bom" ] } } - library("Spring Session Bom", "2022.0.0-SNAPSHOT") { + library("Spring Session Bom", "2022.0.0-M1") { group("org.springframework.session") { imports = [ "spring-session-bom" @@ -1529,7 +1524,7 @@ bom { ] } } - library("Undertow", "2.2.17.Final") { + library("Undertow", "2.2.16.Final") { group("io.undertow") { modules = [ "undertow-core", @@ -1584,13 +1579,6 @@ bom { ] } } - library("Zipkin", "2.16.3") { - group("io.zipkin.reporter2") { - modules = [ - "zipkin-sender-urlconnection" - ] - } - } } generateMetadataFileForMavenPublication { diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java index 26c28ceacec5..1f0a38652c15 100755 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java @@ -18,7 +18,6 @@ import java.io.IOException; import java.io.InputStream; -import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Properties; @@ -75,7 +74,7 @@ public class DevToolsPropertyDefaultsPostProcessor implements EnvironmentPostPro for (String name : properties.stringPropertyNames()) { map.put(name, properties.getProperty(name)); } - PROPERTIES = Collections.unmodifiableMap(map); + PROPERTIES = map; } @Override diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java index 7e4e6832c7eb..b32a603d3fb8 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2020 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. @@ -42,7 +42,6 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; -import org.springframework.http.HttpStatusCode; import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpRequestFactory; @@ -109,7 +108,7 @@ private void performUpload(ClassLoaderFiles classLoaderFiles, byte[] bytes) thro headers.setContentLength(bytes.length); FileCopyUtils.copy(bytes, request.getBody()); ClientHttpResponse response = request.execute(); - HttpStatusCode statusCode = response.getStatusCode(); + HttpStatus statusCode = response.getStatusCode(); Assert.state(statusCode == HttpStatus.OK, () -> "Unexpected " + statusCode + " response uploading class files"); logUpload(classLoaderFiles); diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/Restarter.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/Restarter.java index 9f0f89e83f98..0981ce24a288 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/Restarter.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/Restarter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -350,6 +350,17 @@ private void clearAnnotationUtilsCache() throws Exception { } } + private void clear(String className, String fieldName) { + try { + clear(Class.forName(className), fieldName); + } + catch (Exception ex) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("Unable to clear field " + className + " " + fieldName, ex); + } + } + } + private void clear(Class type, String fieldName) throws Exception { try { Field field = type.getDeclaredField(fieldName); diff --git a/spring-boot-project/spring-boot-docs/build.gradle b/spring-boot-project/spring-boot-docs/build.gradle index 40941a19638b..ba758eb2d812 100644 --- a/spring-boot-project/spring-boot-docs/build.gradle +++ b/spring-boot-project/spring-boot-docs/build.gradle @@ -77,6 +77,7 @@ dependencies { implementation("ch.qos.logback:logback-classic") implementation("com.zaxxer:HikariCP") implementation("io.micrometer:micrometer-core") + implementation("io.micrometer:micrometer-binders") implementation("io.micrometer:micrometer-registry-graphite") implementation("io.micrometer:micrometer-registry-jmx") implementation("io.projectreactor.netty:reactor-netty-http") diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/metrics.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/metrics.adoc index 848c00341dce..bb175b6d64bd 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/metrics.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/metrics.adoc @@ -589,7 +589,9 @@ If you are exporting metrics to https://www.wavefront.com/[Wavefront] directly, ---- management: wavefront: - api-token: "YOUR_API_TOKEN" + metrics: + export: + api-token: "YOUR_API_TOKEN" ---- Alternatively, you can use a Wavefront sidecar or an internal proxy in your environment to forward metrics data to the Wavefront API host: @@ -598,7 +600,9 @@ Alternatively, you can use a Wavefront sidecar or an internal proxy in your envi ---- management: wavefront: - uri: "proxy://localhost:2878" + metrics: + export: + uri: "proxy://localhost:2878" ---- NOTE: If you publish metrics to a Wavefront proxy (as described in https://docs.wavefront.com/proxies_installing.html[the Wavefront documentation]), the host must be in the `proxy://HOST:PORT` format. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/container-images/dockerfiles.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/container-images/dockerfiles.adoc index 6cc5e18cbd3f..c3fb26ec168c 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/container-images/dockerfiles.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/container-images/dockerfiles.adoc @@ -32,13 +32,13 @@ Here is an example of a Dockerfile using `jarmode`. [source,dockerfile,indent=0,subs="verbatim"] ---- -FROM eclipse-temurin:11-jre as builder +FROM adoptopenjdk:11-jre-hotspot as builder WORKDIR application ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} application.jar RUN java -Djarmode=layertools -jar application.jar extract -FROM eclipse-temurin:11-jre +FROM adoptopenjdk:11-jre-hotspot WORKDIR application COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/data/nosql.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/data/nosql.adoc index 10f8d029ed9b..56823d5325d1 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/data/nosql.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/data/nosql.adoc @@ -252,8 +252,9 @@ Spring Boot provides a dedicated "`Starter`", `spring-boot-starter-data-elastics [[data.nosql.elasticsearch.connecting-using-rest]] ==== Connecting to Elasticsearch using REST clients -Elasticsearch ships https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/index.html[two different REST clients] that you can use to query a cluster: the low-level client from the `org.elasticsearch.client:elasticsearch-rest-client` module and the high-level client from the `org.elasticsearch.client:elasticsearch-high-level-client` module. -Additionally, Spring Boot provides support for a reactive client, based on Spring Framework's `WebClient`, from the `org.springframework.data:spring-data-elasticsearch` module. +Elasticsearch ships https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/index.html[two different REST clients] that you can use to query a cluster: the "Low Level" client and the "High Level" client. +Spring Boot provides support for the "High Level" client, which ships with `org.elasticsearch.client:elasticsearch-rest-high-level-client`. +Additionally, Spring Boot provides support for a reactive client, based on Spring Framework's `WebClient`, that ships with `org.springframework.data:spring-data-elasticsearch`. By default, the clients will target `http://localhost:9200`. You can use `spring.elasticsearch.*` properties to further tune how the clients are configured, as shown in the following example: @@ -268,16 +269,14 @@ You can use `spring.elasticsearch.*` properties to further tune how the clients ---- [[data.nosql.elasticsearch.connecting-using-rest.restclient]] -===== Connecting to Elasticsearch using RestClient -If you have `elasticsearch-rest-client` on the classpath, Spring Boot will auto-configure and register a `RestClient` bean. -If you have `elasticsearch-rest-high-level-client` on the classpath a `RestHighLevelClient` bean will be auto-configured as well. -Following Elasticsearch's deprecation of `RestHighLevelClient`, its auto-configuration is deprecated and will be removed in a future release. -In addition to the properties described previously, to fine-tune the `RestClient` and `RestHighLevelClient`, you can register an arbitrary number of beans that implement `RestClientBuilderCustomizer` for more advanced customizations. -To take full control over the clients' configuration, define a `RestClientBuilder` bean. +===== Connecting to Elasticsearch using RestHighLevelClient +If you have `elasticsearch-rest-high-level-client` on the classpath, Spring Boot will auto-configure and register a `RestHighLevelClient` bean. +In addition to the properties described previously, to fine-tune the `RestHighLevelClient`, you can register an arbitrary number of beans that implement `RestClientBuilderCustomizer` for more advanced customizations. +To take full control over its registration, define a `RestClientBuilder` bean. +TIP: If your application needs access to a "Low Level" `RestClient`, you can get it by calling `client.getLowLevelClient()` on the auto-configured `RestHighLevelClient`. - -Additionally, if `elasticsearch-rest-client-sniffer` is on the classpath, a `Sniffer` is auto-configured to automatically discover nodes from a running Elasticsearch cluster and set them on the `RestClient` bean. +Additionally, if `elasticsearch-rest-client-sniffer` is on the classpath, a `Sniffer` is auto-configured to automatically discover nodes from a running Elasticsearch cluster and set them on the `RestHighLevelClient` bean. You can further tune how `Sniffer` is configured, as shown in the following example: [source,yaml,indent=0,subs="verbatim",configprops,configblocks] diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/spring-application.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/spring-application.adoc index a717c744636c..c46dd1297944 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/spring-application.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/spring-application.adoc @@ -352,9 +352,6 @@ include::code:MyApplication[] Also, the `ExitCodeGenerator` interface may be implemented by exceptions. When such an exception is encountered, Spring Boot returns the exit code provided by the implemented `getExitCode()` method. -If there is more than `ExitCodeGenerator`, the first non-zero exit code that is generated is used. -To control the order in which the generators are called, additionally implement the `org.springframework.core.Ordered` interface or use the `org.springframework.core.annotation.Order` annotation. - [[features.spring-application.admin]] diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/webserver.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/webserver.adoc index 2b3649b0b92c..97fb383a2fc3 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/webserver.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/webserver.adoc @@ -59,13 +59,6 @@ If you wish to use Jetty 10, which does support servlet 4.0, you can do so as sh org.springframework.boot spring-boot-starter-tomcat - - - - - org.springframework.boot - spring-boot-starter-jetty - org.eclipse.jetty.websocket @@ -77,6 +70,11 @@ If you wish to use Jetty 10, which does support servlet 4.0, you can do so as sh + + + org.springframework.boot + spring-boot-starter-jetty + ---- Note that along with excluding the Tomcat starter, a couple of Jetty9-specific dependencies also need to be excluded. @@ -183,7 +181,7 @@ You can configure this behavior by setting the configprop:server.compression.mim [[howto.webserver.configure-ssl]] === Configure SSL SSL can be configured declaratively by setting the various `+server.ssl.*+` properties, typically in `application.properties` or `application.yml`. -The following example shows setting SSL properties using a Java KeyStore file: +The following example shows setting SSL properties in `application.properties`: [source,yaml,indent=0,subs="verbatim",configprops,configblocks] ---- @@ -195,19 +193,6 @@ The following example shows setting SSL properties using a Java KeyStore file: key-password: "another-secret" ---- -The following example shows setting SSL properties using PEM-encoded certificate and private key files: - -[source,yaml,indent=0,subs="verbatim",configprops,configblocks] ----- - server: - port: 8443 - ssl: - certificate: "classpath:my-cert.crt" - certificate-private-key: "classpath:my-cert.key" - trust-certificate: "classpath:ca-cert.crt" - key-store-password: "secret" ----- - See {spring-boot-module-code}/web/server/Ssl.java[`Ssl`] for details of all of the supported properties. Using configuration such as the preceding example means the application no longer supports a plain HTTP connector at port 8080. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/messaging/kafka.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/messaging/kafka.adoc index 8cfa6516a5e3..cb4c29f0fe51 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/messaging/kafka.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/messaging/kafka.adoc @@ -61,7 +61,7 @@ The former can be configured using `spring.kafka.streams.application-id`, defaul The latter can be set globally or specifically overridden only for streams. Several additional properties are available using dedicated properties; other arbitrary Kafka properties can be set using the `spring.kafka.streams.properties` namespace. -See also <> for more information. +See also <> for more information. To use the factory bean, wire `StreamsBuilder` into your `@Bean` as shown in the following example: diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/spring-security.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/spring-security.adoc index c7c95443d173..a2370710e7b4 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/spring-security.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/spring-security.adoc @@ -262,7 +262,7 @@ You can register multiple relying parties under the `spring.security.saml2.relyi credentials: - private-key-location: "path-to-private-key" certificate-location: "path-to-certificate" - asserting-party: + identityprovider: verification: credentials: - certificate-location: "path-to-verification-cert" @@ -278,7 +278,7 @@ You can register multiple relying parties under the `spring.security.saml2.relyi credentials: - private-key-location: "path-to-private-key" certificate-location: "path-to-certificate" - asserting-party: + identityprovider: verification: credentials: - certificate-location: "path-to-other-verification-cert" diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/CustomCommandTagsProvider.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/CustomCommandTagsProvider.java index 41014d0ab7c6..17b85d18f08a 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/CustomCommandTagsProvider.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/CustomCommandTagsProvider.java @@ -17,8 +17,8 @@ package org.springframework.boot.docs.actuator.metrics.supported.mongodb.command; import com.mongodb.event.CommandEvent; +import io.micrometer.binder.mongodb.MongoCommandTagsProvider; import io.micrometer.core.instrument.Tag; -import io.micrometer.core.instrument.binder.mongodb.MongoCommandTagsProvider; class CustomCommandTagsProvider implements MongoCommandTagsProvider { diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/MyCommandTagsProviderConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/MyCommandTagsProviderConfiguration.java index ab651b4bf550..c236945c7a33 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/MyCommandTagsProviderConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/MyCommandTagsProviderConfiguration.java @@ -16,7 +16,7 @@ package org.springframework.boot.docs.actuator.metrics.supported.mongodb.command; -import io.micrometer.core.instrument.binder.mongodb.MongoCommandTagsProvider; +import io.micrometer.binder.mongodb.MongoCommandTagsProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/CustomConnectionPoolTagsProvider.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/CustomConnectionPoolTagsProvider.java index 24009433f4a4..fa1dee5db1fd 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/CustomConnectionPoolTagsProvider.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/CustomConnectionPoolTagsProvider.java @@ -17,8 +17,8 @@ package org.springframework.boot.docs.actuator.metrics.supported.mongodb.connectionpool; import com.mongodb.event.ConnectionPoolCreatedEvent; +import io.micrometer.binder.mongodb.MongoConnectionPoolTagsProvider; import io.micrometer.core.instrument.Tag; -import io.micrometer.core.instrument.binder.mongodb.MongoConnectionPoolTagsProvider; public class CustomConnectionPoolTagsProvider implements MongoConnectionPoolTagsProvider { diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/MyConnectionPoolTagsProviderConfiguration.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/MyConnectionPoolTagsProviderConfiguration.java index 8e4d09cbd03e..0d6954fba2bb 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/MyConnectionPoolTagsProviderConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/MyConnectionPoolTagsProviderConfiguration.java @@ -16,7 +16,7 @@ package org.springframework.boot.docs.actuator.metrics.supported.mongodb.connectionpool; -import io.micrometer.core.instrument.binder.mongodb.MongoConnectionPoolTagsProvider; +import io.micrometer.binder.mongodb.MongoConnectionPoolTagsProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringdataelasticsearch/MyDataElasticsearchTests.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringdataelasticsearch/MyDataElasticsearchTests.java index d2c0190773b3..42fc3f903caf 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringdataelasticsearch/MyDataElasticsearchTests.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringdataelasticsearch/MyDataElasticsearchTests.java @@ -20,7 +20,7 @@ import org.springframework.boot.test.autoconfigure.data.elasticsearch.DataElasticsearchTest; @DataElasticsearchTest -class MyDataElasticsearchTests { +public class MyDataElasticsearchTests { @Autowired @SuppressWarnings("unused") diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.java index d3a4f8c0620b..9799fbfa4b90 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.java @@ -23,7 +23,7 @@ import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.is; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.java index a88776943ea8..520e6e3b1aa0 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -18,7 +18,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) public class MyWebIntegrationTests { diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/CustomCommandTagsProvider.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/CustomCommandTagsProvider.kt index b6353022db2d..34ce16d9ff9c 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/CustomCommandTagsProvider.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/CustomCommandTagsProvider.kt @@ -17,8 +17,8 @@ package org.springframework.boot.docs.actuator.metrics.supported.mongodb.command import com.mongodb.event.CommandEvent +import io.micrometer.binder.mongodb.MongoCommandTagsProvider import io.micrometer.core.instrument.Tag -import io.micrometer.core.instrument.binder.mongodb.MongoCommandTagsProvider class CustomCommandTagsProvider : MongoCommandTagsProvider { diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/MyCommandTagsProviderConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/MyCommandTagsProviderConfiguration.kt index 91bcab1c9608..796ad6dad5c6 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/MyCommandTagsProviderConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/command/MyCommandTagsProviderConfiguration.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.actuator.metrics.supported.mongodb.command -import io.micrometer.core.instrument.binder.mongodb.MongoCommandTagsProvider +import io.micrometer.binder.mongodb.MongoCommandTagsProvider import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/CustomConnectionPoolTagsProvider.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/CustomConnectionPoolTagsProvider.kt index 8a766cd5c243..f05a1fdf56b4 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/CustomConnectionPoolTagsProvider.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/CustomConnectionPoolTagsProvider.kt @@ -17,8 +17,8 @@ package org.springframework.boot.docs.actuator.metrics.supported.mongodb.connectionpool import com.mongodb.event.ConnectionPoolCreatedEvent +import io.micrometer.binder.mongodb.MongoConnectionPoolTagsProvider import io.micrometer.core.instrument.Tag -import io.micrometer.core.instrument.binder.mongodb.MongoConnectionPoolTagsProvider class CustomConnectionPoolTagsProvider : MongoConnectionPoolTagsProvider { diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/MyConnectionPoolTagsProviderConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/MyConnectionPoolTagsProviderConfiguration.kt index 0c56242fa3a9..260b889cbb44 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/MyConnectionPoolTagsProviderConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/metrics/supported/mongodb/connectionpool/MyConnectionPoolTagsProviderConfiguration.kt @@ -16,7 +16,7 @@ package org.springframework.boot.docs.actuator.metrics.supported.mongodb.connectionpool -import io.micrometer.core.instrument.binder.mongodb.MongoConnectionPoolTagsProvider +import io.micrometer.binder.mongodb.MongoConnectionPoolTagsProvider import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.kt index b9b8b0e301d9..1a8be789a4b0 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/features/testing/springbootapplications/autoconfiguredspringrestdocs/withrestassured/MyUserDocumentationTests.kt @@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest.WebEnvironment -import org.springframework.boot.test.web.server.LocalServerPort +import org.springframework.boot.web.server.LocalServerPort import org.springframework.restdocs.restassured.RestAssuredRestDocumentation @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @@ -41,4 +41,4 @@ class MyUserDocumentationTests { .statusCode(Matchers.`is`(200)) } -} +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.kt index 12b182578b3d..627bd8b3fb96 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/howto/webserver/discoverport/MyWebIntegrationTests.kt @@ -18,7 +18,7 @@ package org.springframework.boot.docs.howto.webserver.discoverport import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest.WebEnvironment -import org.springframework.boot.test.web.server.LocalServerPort +import org.springframework.boot.web.server.LocalServerPort @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class MyWebIntegrationTests { diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-actuator/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-actuator/build.gradle index 3e2a471593a3..74a593dd2906 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-actuator/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-actuator/build.gradle @@ -9,4 +9,5 @@ dependencies { api(project(":spring-boot-project:spring-boot-actuator-autoconfigure")) api("io.micrometer:micrometer-observation") api("io.micrometer:micrometer-core") + api("io.micrometer:micrometer-binders") } diff --git a/spring-boot-project/spring-boot-test-autoconfigure/build.gradle b/spring-boot-project/spring-boot-test-autoconfigure/build.gradle index 6a5e602f328f..615c1c88c45a 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-test-autoconfigure/build.gradle @@ -68,6 +68,7 @@ dependencies { testImplementation("com.unboundid:unboundid-ldapsdk") testImplementation("io.lettuce:lettuce-core") testImplementation("io.micrometer:micrometer-registry-prometheus") + testImplementation("io.micrometer:micrometer-binders") testImplementation("io.projectreactor.netty:reactor-netty-http") testImplementation("io.projectreactor:reactor-core") testImplementation("io.projectreactor:reactor-test") diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java index 4a83fc38b630..c869a9472462 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java @@ -26,8 +26,8 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.testsupport.BuildOutput; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.annotation.Bean; import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation; import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationIntegrationTests.java index 5d763f790b31..092daf284e99 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationIntegrationTests.java @@ -25,8 +25,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.testsupport.BuildOutput; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.util.FileSystemUtils; import static io.restassured.RestAssured.given; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java index 3e0e48bf448d..148c2f41e7f1 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java @@ -55,7 +55,6 @@ import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; -import org.springframework.web.context.ConfigurableWebApplicationContext; import org.springframework.web.context.support.GenericWebApplicationContext; /** @@ -104,21 +103,14 @@ public ApplicationContext loadContext(MergedContextConfiguration config) throws } else if (config instanceof ReactiveWebMergedContextConfiguration) { application.setWebApplicationType(WebApplicationType.REACTIVE); + if (!isEmbeddedWebEnvironment(config)) { + application.setApplicationContextFactory( + ApplicationContextFactory.of(GenericReactiveWebApplicationContext::new)); + } } else { application.setWebApplicationType(WebApplicationType.NONE); } - application.setApplicationContextFactory((type) -> { - if (type != WebApplicationType.NONE && !isEmbeddedWebEnvironment(config)) { - if (type == WebApplicationType.REACTIVE) { - return new GenericReactiveWebApplicationContext(); - } - else if (type == WebApplicationType.SERVLET) { - return new GenericWebApplicationContext(); - } - } - return ApplicationContextFactory.DEFAULT.create(type); - }); application.setInitializers(initializers); ConfigurableEnvironment environment = getEnvironment(); if (environment != null) { @@ -269,38 +261,14 @@ void configure(MergedContextConfiguration configuration, SpringApplication appli List> initializers) { WebMergedContextConfiguration webConfiguration = (WebMergedContextConfiguration) configuration; addMockServletContext(initializers, webConfiguration); + application.setApplicationContextFactory((webApplicationType) -> new GenericWebApplicationContext()); } private void addMockServletContext(List> initializers, WebMergedContextConfiguration webConfiguration) { SpringBootMockServletContext servletContext = new SpringBootMockServletContext( webConfiguration.getResourceBasePath()); - initializers.add(0, new DefensiveWebApplicationContextInitializer( - new ServletContextApplicationContextInitializer(servletContext, true))); - } - - /** - * Decorator for {@link ServletContextApplicationContextInitializer} that prevents - * a failure when the context type is not as was predicted when the initializer - * was registered. This can occur when spring.main.web-application-type is set to - * something other than servlet. - */ - private static final class DefensiveWebApplicationContextInitializer - implements ApplicationContextInitializer { - - private final ServletContextApplicationContextInitializer delegate; - - private DefensiveWebApplicationContextInitializer(ServletContextApplicationContextInitializer delegate) { - this.delegate = delegate; - } - - @Override - public void initialize(ConfigurableApplicationContext applicationContext) { - if (applicationContext instanceof ConfigurableWebApplicationContext) { - this.delegate.initialize((ConfigurableWebApplicationContext) applicationContext); - } - } - + initializers.add(0, new ServletContextApplicationContextInitializer(servletContext, true)); } } diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTest.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTest.java index 6fed9ffb26df..d069745393f4 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTest.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2020 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. @@ -29,8 +29,8 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.WebApplicationType; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java index c89ae886da43..31ae6e769a56 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -290,13 +290,9 @@ protected void processPropertySourceProperties(MergedContextConfiguration merged // precedence propertySourceProperties.addAll(0, Arrays.asList(properties)); } - WebEnvironment webEnvironment = getWebEnvironment(testClass); - if (webEnvironment == WebEnvironment.RANDOM_PORT) { + if (getWebEnvironment(testClass) == WebEnvironment.RANDOM_PORT) { propertySourceProperties.add("server.port=0"); } - else if (webEnvironment == WebEnvironment.NONE) { - propertySourceProperties.add("spring.main.web-application-type=none"); - } } /** diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/rsocket/server/LocalRSocketServerPort.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/rsocket/server/LocalRSocketServerPort.java deleted file mode 100644 index a80e6cf6143e..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/rsocket/server/LocalRSocketServerPort.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2012-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.boot.test.rsocket.server; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.beans.factory.annotation.Value; - -/** - * Annotation at the field or method/constructor parameter level that injects the RSocket - * port that was allocated at runtime. Provides a convenient alternative for - * @Value("${local.rsocket.server.port}"). - * - * @author Verónica Vásquez - * @author Eddú Meléndez - * @since 2.7.0 - */ -@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Value("${local.rsocket.server.port}") -public @interface LocalRSocketServerPort { - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/rsocket/server/package-info.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/rsocket/server/package-info.java deleted file mode 100644 index 579c40b36497..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/rsocket/server/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-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. - */ - -/** - * RSocket server test utilities and support classes. - */ -package org.springframework.boot.test.rsocket.server; diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalManagementPort.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalManagementPort.java deleted file mode 100644 index a5a51f016c48..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalManagementPort.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2012-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.boot.test.web.server; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.beans.factory.annotation.Value; - -/** - * Annotation at the field or method/constructor parameter level that injects the HTTP - * management port that was allocated at runtime. Provides a convenient alternative for - * @Value("${local.management.port}"). - * - * @author Stephane Nicoll - * @since 2.7.0 - */ -@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Value("${local.management.port}") -public @interface LocalManagementPort { - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalServerPort.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalServerPort.java deleted file mode 100644 index ff7929ca6873..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/LocalServerPort.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2012-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.boot.test.web.server; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.beans.factory.annotation.Value; - -/** - * Annotation at the field or method/constructor parameter level that injects the HTTP - * server port that was allocated at runtime. Provides a convenient alternative for - * @Value("${local.server.port}"). - * - * @author Anand Shah - * @author Stephane Nicoll - * @since 2.7.0 - */ -@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Value("${local.server.port}") -public @interface LocalServerPort { - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/package-info.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/package-info.java deleted file mode 100644 index 3fd756a102bc..000000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/server/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-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. - */ - -/** - * Web server test utilities and support classes. - */ -package org.springframework.boot.test.web.server; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java index 24fa63ae5e2f..2aa871007d6d 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -24,10 +24,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestWebServerWebEnvironmentTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestWebServerWebEnvironmentTests.java index 5f81f51cfa00..dbe55f5ce0b0 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestWebServerWebEnvironmentTests.java +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestWebServerWebEnvironmentTests.java @@ -22,8 +22,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootContextLoaderTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootContextLoaderTests.java index 3b9f4a5050b1..ad03d67f4a02 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootContextLoaderTests.java +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootContextLoaderTests.java @@ -24,7 +24,6 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.web.reactive.context.GenericReactiveWebApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.ConfigurableEnvironment; @@ -37,7 +36,6 @@ import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.support.TestPropertySourceUtils; import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.web.context.WebApplicationContext; import static org.assertj.core.api.Assertions.assertThat; @@ -148,20 +146,6 @@ void propertySourceOrdering() throws Exception { assertThat(last).startsWith("Config resource"); } - @Test - void whenEnvironmentChangesWebApplicationTypeToNoneThenContextTypeChangesAccordingly() { - TestContext context = new ExposedTestContextManager(ChangingWebApplicationTypeToNone.class) - .getExposedTestContext(); - assertThat(context.getApplicationContext()).isNotInstanceOf(WebApplicationContext.class); - } - - @Test - void whenEnvironmentChangesWebApplicationTypeToReactiveThenContextTypeChangesAccordingly() { - TestContext context = new ExposedTestContextManager(ChangingWebApplicationTypeToReactive.class) - .getExposedTestContext(); - assertThat(context.getApplicationContext()).isInstanceOf(GenericReactiveWebApplicationContext.class); - } - private String[] getActiveProfiles(Class testClass) { TestContext testContext = new ExposedTestContextManager(testClass).getExposedTestContext(); ApplicationContext applicationContext = testContext.getApplicationContext(); @@ -244,16 +228,6 @@ static class Config { } - @SpringBootTest(classes = Config.class, args = "--spring.main.web-application-type=none") - static class ChangingWebApplicationTypeToNone { - - } - - @SpringBootTest(classes = Config.class, args = "--spring.main.web-application-type=reactive") - static class ChangingWebApplicationTypeToReactive { - - } - /** * {@link TestContextManager} which exposes the {@link TestContext}. */ diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/rsocket/server/LocalRSocketServerPortTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/rsocket/server/LocalRSocketServerPortTests.java deleted file mode 100644 index 59b12f58d20d..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/rsocket/server/LocalRSocketServerPortTests.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2012-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.boot.test.rsocket.server; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link LocalRSocketServerPort @LocalRSocketServerPort}. - * - * @author Verónica Vásquez - * @author Eddú Meléndez - */ -@ExtendWith(SpringExtension.class) -@TestPropertySource(properties = "local.rsocket.server.port=8181") -class LocalRSocketServerPortTests { - - @Value("${local.rsocket.server.port}") - private String fromValue; - - @LocalRSocketServerPort - private String fromAnnotation; - - @Test - void testLocalRSocketServerPortAnnotation() { - assertThat(this.fromAnnotation).isNotNull().isEqualTo(this.fromValue); - } - - @Configuration(proxyBeanMethods = false) - static class Config { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalManagementPortTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalManagementPortTests.java deleted file mode 100644 index 8be0c26f78ce..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalManagementPortTests.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-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.boot.test.web.server; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link LocalManagementPort @LocalManagementPort}. - * - * @author Andy Wilkinson - */ -@ExtendWith(SpringExtension.class) -@TestPropertySource(properties = "local.management.port=8181") -class LocalManagementPortTests { - - @Value("${local.management.port}") - private String fromValue; - - @LocalManagementPort - private String fromAnnotation; - - @Test - void testLocalManagementPortAnnotation() { - assertThat(this.fromAnnotation).isNotNull().isEqualTo(this.fromValue); - } - - @Configuration(proxyBeanMethods = false) - static class Config { - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalServerPortTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalServerPortTests.java deleted file mode 100644 index 3855f5115f7c..000000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/server/LocalServerPortTests.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2012-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.boot.test.web.server; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link LocalServerPort @LocalServerPort}. - * - * @author Anand Shah - * @author Phillip Webb - */ -@ExtendWith(SpringExtension.class) -@TestPropertySource(properties = "local.server.port=8181") -class LocalServerPortTests { - - @Value("${local.server.port}") - private String fromValue; - - @LocalServerPort - private String fromAnnotation; - - @Test - void testLocalServerPortAnnotation() { - assertThat(this.fromAnnotation).isNotNull().isEqualTo(this.fromValue); - } - - @Configuration(proxyBeanMethods = false) - static class Config { - - } - -} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/ApiVersions.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/ApiVersions.java index 9b02d9796b98..fdbef611d6f6 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/ApiVersions.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/ApiVersions.java @@ -17,7 +17,8 @@ package org.springframework.boot.buildpack.platform.build; import java.util.Arrays; -import java.util.stream.IntStream; +import java.util.List; +import java.util.stream.Collectors; import org.springframework.util.StringUtils; @@ -31,7 +32,8 @@ final class ApiVersions { /** * The platform API versions supported by this release. */ - static final ApiVersions SUPPORTED_PLATFORMS = ApiVersions.of(0, IntStream.rangeClosed(3, 9)); + static final ApiVersions SUPPORTED_PLATFORMS = new ApiVersions(ApiVersion.of(0, 3), ApiVersion.of(0, 4), + ApiVersion.of(0, 5), ApiVersion.of(0, 6), ApiVersion.of(0, 7), ApiVersion.of(0, 8)); private final ApiVersion[] apiVersions; @@ -90,12 +92,8 @@ public String toString() { * @throws IllegalArgumentException if any values could not be parsed */ static ApiVersions parse(String... values) { - return new ApiVersions(Arrays.stream(values).map(ApiVersion::parse).toArray(ApiVersion[]::new)); - } - - static ApiVersions of(int major, IntStream minorsInclusive) { - return new ApiVersions( - minorsInclusive.mapToObj((minor) -> ApiVersion.of(major, minor)).toArray(ApiVersion[]::new)); + List versions = Arrays.stream(values).map(ApiVersion::parse).collect(Collectors.toList()); + return new ApiVersions(versions.toArray(new ApiVersion[] {})); } } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/ApiVersionsTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/ApiVersionsTests.java index cdaa17d9dd39..421f2a191062 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/ApiVersionsTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/ApiVersionsTests.java @@ -16,8 +16,6 @@ package org.springframework.boot.buildpack.platform.build; -import java.util.stream.IntStream; - import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -67,12 +65,6 @@ void findLatestWhenNoneSupportedThrowsException() { "Detected platform API versions '1.3,1.4' are not included in supported versions '1.1,1.2'"); } - @Test - void createFromRange() { - ApiVersions versions = ApiVersions.of(1, IntStream.rangeClosed(2, 7)); - assertThat(versions.toString()).isEqualTo("1.2,1.3,1.4,1.5,1.6,1.7"); - } - @Test void toStringReturnsString() { assertThat(ApiVersions.parse("1.1", "2.2", "3.3").toString()).isEqualTo("1.1,2.2,3.3"); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/LifecycleTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/LifecycleTests.java index a641427c28ae..6aa6f04c81ba 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/LifecycleTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/LifecycleTests.java @@ -161,8 +161,8 @@ void executeWhenPlatformApiNotSupportedThrowsException() throws Exception { given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId()); given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null)); assertThatIllegalStateException() - .isThrownBy(() -> createLifecycle("builder-metadata-unsupported-api.json").execute()) - .withMessageContaining("Detected platform API versions '0.2' are not included in supported versions"); + .isThrownBy(() -> createLifecycle("builder-metadata-unsupported-api.json").execute()).withMessage( + "Detected platform API versions '0.2' are not included in supported versions '0.3,0.4,0.5,0.6,0.7,0.8'"); } @Test @@ -171,9 +171,8 @@ void executeWhenMultiplePlatformApisNotSupportedThrowsException() throws Excepti given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId()); given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null)); assertThatIllegalStateException() - .isThrownBy(() -> createLifecycle("builder-metadata-unsupported-apis.json").execute()) - .withMessageContaining( - "Detected platform API versions '0.1,0.2' are not included in supported versions"); + .isThrownBy(() -> createLifecycle("builder-metadata-unsupported-apis.json").execute()).withMessage( + "Detected platform API versions '0.1,0.2' are not included in supported versions '0.3,0.4,0.5,0.6,0.7,0.8'"); } @Test diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataGenerationEnvironment.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataGenerationEnvironment.java index 12e74e475963..fc0580285ddf 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataGenerationEnvironment.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataGenerationEnvironment.java @@ -221,6 +221,10 @@ List getElementsAnnotatedOrMetaAnnotatedWith(Element element, TypeEleme return Collections.unmodifiableList(stack); } + private boolean hasAnnotationRecursive(Element element, String type) { + return !getElementsAnnotatedOrMetaAnnotatedWith(element, this.elements.getTypeElement(type)).isEmpty(); + } + private boolean collectElementsAnnotatedOrMetaAnnotatedWith(TypeElement annotationType, LinkedList stack) { Element element = stack.peekLast(); for (AnnotationMirror annotation : this.elements.getAllAnnotationMirrors(element)) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/running.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/running.adoc index b178f1277625..9c230e6f7121 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/running.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/running.adoc @@ -123,7 +123,7 @@ The preceding example sets the value of the `example` project property to `custo [[running-your-application.reloading-resources]] == Reloading Resources If devtools has been added to your project it will automatically monitor your application's classpath for changes. -Note that modified files need to be recompiled for the classpath to update in order to trigger reloading with devtools. +Note that modified files need to be recompiled for the classpath to update inorder to trigger reloading with devtools. For more details on using devtools, refer to {spring-boot-reference}#using.devtools.restart[this section of the reference documentation]. Alternatively, you can configure `bootRun` such that your application's static resources are loaded from their source location: diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java index 993937d7b0e7..315d587220f3 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -110,7 +110,7 @@ public void properties(Action action) { private Map coerceToStringValues(Map input) { Map output = new HashMap<>(); - input.forEach((key, value) -> output.put(key, (value != null) ? value.toString() : null)); + input.forEach((key, value) -> output.put(key, value.toString())); return output; } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java index e1c86f4ab761..441ebd4d2459 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -33,7 +33,6 @@ import org.springframework.boot.testsupport.classpath.ClassPathExclusions; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * Tests for {@link BuildInfo}. @@ -187,14 +186,6 @@ void additionalPropertiesAreReflectedInProperties() { assertThat(buildInfoProperties(task)).containsEntry("build.b", "bravo"); } - @Test - void nullAdditionalPropertyProducesInformativeFailure() { - BuildInfo task = createTask(createProject("test")); - task.getProperties().getAdditional().put("a", null); - assertThatThrownBy(() -> buildInfoProperties(task)) - .hasMessage("Additional property 'a' is illegal as its value is null"); - } - private Project createProject(String projectName) { File projectDir = new File(this.temp, projectName); Project project = GradleProjectBuilder.builder().withProjectDir(projectDir).withName(projectName).build(); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-test-support/src/main/java/org/springframework/boot/testsupport/gradle/testkit/GradleBuild.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-test-support/src/main/java/org/springframework/boot/testsupport/gradle/testkit/GradleBuild.java index 7268df47aa1c..b9ecb49186fb 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-test-support/src/main/java/org/springframework/boot/testsupport/gradle/testkit/GradleBuild.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-test-support/src/main/java/org/springframework/boot/testsupport/gradle/testkit/GradleBuild.java @@ -184,7 +184,7 @@ public BuildResult build(String... arguments) { buildOutput = buildOutput.replaceAll(message, ""); } } - assertThat(buildOutput).doesNotContainIgnoringCase("deprecated"); + assertThat(buildOutput).doesNotContain("Deprecated").doesNotContain("deprecated"); } return result; } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ExitCodeGenerators.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ExitCodeGenerators.java index 489f23ec8715..f26f16ea166d 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ExitCodeGenerators.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ExitCodeGenerators.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -21,19 +21,14 @@ import java.util.Iterator; import java.util.List; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.core.annotation.Order; import org.springframework.util.Assert; /** - * Maintains an ordered collection of {@link ExitCodeGenerator} instances and allows the - * final exit code to be calculated. Generators are ordered by {@link Order @Order} and - * {@link Ordered}. + * Maintains a collection of {@link ExitCodeGenerator} instances and allows the final exit + * code to be calculated. * * @author Dave Syer * @author Phillip Webb - * @author GenKui Du * @see #getExitCode() * @see ExitCodeGenerator */ @@ -76,7 +71,6 @@ void addAll(Iterable generators) { void add(ExitCodeGenerator generator) { Assert.notNull(generator, "Generator must not be null"); this.generators.add(generator); - AnnotationAwareOrderComparator.sort(this.generators); } @Override @@ -85,8 +79,7 @@ public Iterator iterator() { } /** - * Get the final exit code that should be returned. The final exit code is the first - * non-zero exit code that is {@link ExitCodeGenerator#getExitCode generated}. + * Get the final exit code that should be returned based on all contained generators. * @return the final exit code. */ int getExitCode() { @@ -94,13 +87,12 @@ int getExitCode() { for (ExitCodeGenerator generator : this.generators) { try { int value = generator.getExitCode(); - if (value != 0) { + if (value > 0 && value > exitCode || value < 0 && value < exitCode) { exitCode = value; - break; } } catch (Exception ex) { - exitCode = 1; + exitCode = (exitCode != 0) ? exitCode : 1; ex.printStackTrace(); } } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java index e3075cad8b7b..7f1910c61124 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java @@ -61,9 +61,7 @@ import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.GenericTypeResolver; -import org.springframework.core.Ordered; import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.core.annotation.Order; import org.springframework.core.env.CommandLinePropertySource; import org.springframework.core.env.CompositePropertySource; import org.springframework.core.env.ConfigurableEnvironment; @@ -1322,10 +1320,9 @@ public static void main(String[] args) throws Exception { * Static helper that can be used to exit a {@link SpringApplication} and obtain a * code indicating success (0) or otherwise. Does not throw exceptions but should * print stack traces of any encountered. Applies the specified - * {@link ExitCodeGenerator ExitCodeGenerators} in addition to any Spring beans that - * implement {@link ExitCodeGenerator}. When multiple generators are available, the - * first non-zero exit code is used. Generators ordered based on their {@link Ordered} - * implementation and {@link Order @Order} annotation. + * {@link ExitCodeGenerator} in addition to any Spring beans that implement + * {@link ExitCodeGenerator}. In the case of multiple exit codes the highest value + * will be used (or if all values are negative, the lowest value will be used) * @param context the context to close if possible * @param exitCodeGenerators exit code generators * @return the outcome (0 if successful) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/annotation/Configurations.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/annotation/Configurations.java index 522c1469bc83..59056d2e8e1a 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/annotation/Configurations.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/annotation/Configurations.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -33,7 +33,6 @@ import org.springframework.context.annotation.ImportSelector; import org.springframework.core.OrderComparator; import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -48,8 +47,8 @@ * This class is primarily intended for use with tests that need to specify configuration * classes but can't use {@link SpringRunner}. *

- * Implementations of this class should be annotated with {@link Order @Order} or - * implement {@link Ordered}. + * Implementations of this class should be annotated with {@code @Order} or implement + * {@link Ordered}. * * @author Phillip Webb * @since 2.0.0 diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBean.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBean.java index ecf7e2732cc3..be59be46351b 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBean.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBean.java @@ -148,12 +148,8 @@ public static Map getAll(ApplicationContext return getAll((ConfigurableApplicationContext) applicationContext); } Map propertiesBeans = new LinkedHashMap<>(); - applicationContext.getBeansWithAnnotation(ConfigurationProperties.class).forEach((beanName, bean) -> { - ConfigurationPropertiesBean propertiesBean = get(applicationContext, bean, beanName); - if (propertiesBean != null) { - propertiesBeans.put(beanName, propertiesBean); - } - }); + applicationContext.getBeansWithAnnotation(ConfigurationProperties.class) + .forEach((beanName, bean) -> propertiesBeans.put(beanName, get(applicationContext, bean, beanName))); return propertiesBeans; } @@ -167,9 +163,7 @@ private static Map getAll(ConfigurableAppli try { Object bean = beanFactory.getBean(beanName); ConfigurationPropertiesBean propertiesBean = get(applicationContext, bean, beanName); - if (propertiesBean != null) { - propertiesBeans.put(beanName, propertiesBean); - } + propertiesBeans.put(beanName, propertiesBean); } catch (Exception ex) { } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/FailureAnalyzers.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/FailureAnalyzers.java index d493c47894e3..df040bfb8681 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/FailureAnalyzers.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/FailureAnalyzers.java @@ -90,9 +90,9 @@ private List handleAwareAnalyzers(List analyze String awareAnalyzerNames = StringUtils.collectionToCommaDelimitedString(awareAnalyzers.stream() .map((analyzer) -> analyzer.getClass().getName()).collect(Collectors.toList())); logger.warn(LogMessage.format( - "FailureAnalyzers [%s] implement BeanFactoryAware or EnvironmentAware. " + "FailureAnalyzers [%s] implement BeanFactoryAware or EnvironmentAware." + "Support for these interfaces on FailureAnalyzers is deprecated, " - + "and will be removed in a future release. " + + "and will be removed in a future release." + "Instead provide a constructor that accepts BeanFactory or Environment parameters.", awareAnalyzerNames)); if (context == null) { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/BeanCurrentlyInCreationFailureAnalyzer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/BeanCurrentlyInCreationFailureAnalyzer.java index 44de27d6cbd5..aa9786023066 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/BeanCurrentlyInCreationFailureAnalyzer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/BeanCurrentlyInCreationFailureAnalyzer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -19,9 +19,11 @@ import java.util.ArrayList; import java.util.List; +import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanCurrentlyInCreationException; import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.InjectionPoint; import org.springframework.beans.factory.UnsatisfiedDependencyException; import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory; @@ -34,19 +36,17 @@ * {@link BeanCurrentlyInCreationException}. * * @author Andy Wilkinson - * @author Scott Frederick */ -class BeanCurrentlyInCreationFailureAnalyzer extends AbstractFailureAnalyzer { +class BeanCurrentlyInCreationFailureAnalyzer extends AbstractFailureAnalyzer + implements BeanFactoryAware { - private final AbstractAutowireCapableBeanFactory beanFactory; + private AbstractAutowireCapableBeanFactory beanFactory; - BeanCurrentlyInCreationFailureAnalyzer(BeanFactory beanFactory) { - if (beanFactory != null && beanFactory instanceof AbstractAutowireCapableBeanFactory) { + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + if (beanFactory instanceof AbstractAutowireCapableBeanFactory) { this.beanFactory = (AbstractAutowireCapableBeanFactory) beanFactory; } - else { - this.beanFactory = null; - } } @Override diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/InvalidConfigurationPropertyValueFailureAnalyzer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/InvalidConfigurationPropertyValueFailureAnalyzer.java index 7f1cff00907b..e9ab9ab6cdfb 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/InvalidConfigurationPropertyValueFailureAnalyzer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/InvalidConfigurationPropertyValueFailureAnalyzer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -27,6 +27,7 @@ import org.springframework.boot.diagnostics.FailureAnalyzer; import org.springframework.boot.origin.Origin; import org.springframework.boot.origin.OriginLookup; +import org.springframework.context.EnvironmentAware; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; import org.springframework.core.env.PropertySource; @@ -37,14 +38,14 @@ * {@link InvalidConfigurationPropertyValueException}. * * @author Stephane Nicoll - * @author Scott Frederick */ class InvalidConfigurationPropertyValueFailureAnalyzer - extends AbstractFailureAnalyzer { + extends AbstractFailureAnalyzer implements EnvironmentAware { - private final ConfigurableEnvironment environment; + private ConfigurableEnvironment environment; - InvalidConfigurationPropertyValueFailureAnalyzer(Environment environment) { + @Override + public void setEnvironment(Environment environment) { this.environment = (ConfigurableEnvironment) environment; } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/MutuallyExclusiveConfigurationPropertiesFailureAnalyzer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/MutuallyExclusiveConfigurationPropertiesFailureAnalyzer.java index 56bac16c92c1..429aa21f5fc3 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/MutuallyExclusiveConfigurationPropertiesFailureAnalyzer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/MutuallyExclusiveConfigurationPropertiesFailureAnalyzer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -32,23 +32,24 @@ import org.springframework.boot.diagnostics.FailureAnalyzer; import org.springframework.boot.origin.Origin; import org.springframework.boot.origin.OriginLookup; +import org.springframework.context.EnvironmentAware; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; import org.springframework.core.env.PropertySource; /** - * A {@link FailureAnalyzer} that performs analysis of failures caused by a + * A {@link FailureAnalyzer} that performs analysis of failures caused by an * {@link MutuallyExclusiveConfigurationPropertiesException}. * * @author Andy Wilkinson - * @author Scott Frederick */ class MutuallyExclusiveConfigurationPropertiesFailureAnalyzer - extends AbstractFailureAnalyzer { + extends AbstractFailureAnalyzer implements EnvironmentAware { - private final ConfigurableEnvironment environment; + private ConfigurableEnvironment environment; - MutuallyExclusiveConfigurationPropertiesFailureAnalyzer(Environment environment) { + @Override + public void setEnvironment(Environment environment) { this.environment = (ConfigurableEnvironment) environment; } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzer.java index 555df79bce1f..aa2e540954ba 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -16,7 +16,9 @@ package org.springframework.boot.diagnostics.analyzer; +import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.NoUniqueBeanDefinitionException; import org.springframework.beans.factory.config.BeanDefinition; @@ -30,13 +32,14 @@ * by a {@link NoUniqueBeanDefinitionException}. * * @author Andy Wilkinson - * @author Scott Frederick */ -class NoUniqueBeanDefinitionFailureAnalyzer extends AbstractInjectionFailureAnalyzer { +class NoUniqueBeanDefinitionFailureAnalyzer extends AbstractInjectionFailureAnalyzer + implements BeanFactoryAware { - private final ConfigurableBeanFactory beanFactory; + private ConfigurableBeanFactory beanFactory; - NoUniqueBeanDefinitionFailureAnalyzer(BeanFactory beanFactory) { + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { Assert.isInstanceOf(ConfigurableBeanFactory.class, beanFactory); this.beanFactory = (ConfigurableBeanFactory) beanFactory; } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DatabaseDriver.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DatabaseDriver.java index 03ba0c1deff6..8b682f6d482c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DatabaseDriver.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DatabaseDriver.java @@ -76,6 +76,11 @@ public enum DatabaseDriver { */ MARIADB("MariaDB", "org.mariadb.jdbc.Driver", "org.mariadb.jdbc.MariaDbDataSource", "SELECT 1"), + /** + * Google App Engine. + */ + GAE(null, "com.google.appengine.api.rdbms.AppEngineDriver"), + /** * Oracle. */ diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/LocalRSocketServerPort.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/LocalRSocketServerPort.java index b64f4ca3d5ca..7da1f6a32c93 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/LocalRSocketServerPort.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/context/LocalRSocketServerPort.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -32,14 +32,11 @@ * @author Verónica Vásquez * @author Eddú Meléndez * @since 2.2.0 - * @deprecated since 2.7.0 for removal in 2.9.0 in favor of - * {@code org.springframework.boot.test.rsocket.LocalRSocketServerPort} */ @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) @Retention(RetentionPolicy.RUNTIME) @Documented @Value("${local.rsocket.server.port}") -@Deprecated public @interface LocalRSocketServerPort { } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java index 89f44959ede4..1ea7e2b80124 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -39,7 +39,6 @@ import org.springframework.boot.rsocket.server.RSocketServer; import org.springframework.boot.rsocket.server.RSocketServerCustomizer; import org.springframework.boot.rsocket.server.RSocketServerFactory; -import org.springframework.boot.web.server.CertificateFileSslStoreProvider; import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.SslStoreProvider; import org.springframework.http.client.reactive.ReactorResourceFactory; @@ -52,7 +51,6 @@ * * @author Brian Clozel * @author Chris Bono - * @author Scott Frederick * @since 2.2.0 */ public class NettyRSocketServerFactory implements RSocketServerFactory, ConfigurableRSocketServerFactory { @@ -181,7 +179,7 @@ private ServerTransport createWebSocketTransport() { @SuppressWarnings("deprecation") private HttpServer customizeSslConfiguration(HttpServer httpServer) { org.springframework.boot.web.embedded.netty.SslServerCustomizer sslServerCustomizer = new org.springframework.boot.web.embedded.netty.SslServerCustomizer( - this.ssl, null, getOrCreateSslStoreProvider()); + this.ssl, null, this.sslStoreProvider); return sslServerCustomizer.apply(httpServer); } @@ -191,20 +189,12 @@ private ServerTransport createTcpTransport() { tcpServer = tcpServer.runOn(this.resourceFactory.getLoopResources()); } if (this.ssl != null && this.ssl.isEnabled()) { - TcpSslServerCustomizer sslServerCustomizer = new TcpSslServerCustomizer(this.ssl, - getOrCreateSslStoreProvider()); + TcpSslServerCustomizer sslServerCustomizer = new TcpSslServerCustomizer(this.ssl, this.sslStoreProvider); tcpServer = sslServerCustomizer.apply(tcpServer); } return TcpServerTransport.create(tcpServer.bindAddress(this::getListenAddress)); } - private SslStoreProvider getOrCreateSslStoreProvider() { - if (this.sslStoreProvider != null) { - return this.sslStoreProvider; - } - return CertificateFileSslStoreProvider.from(this.ssl); - } - private InetSocketAddress getListenAddress() { if (this.address != null) { return new InetSocketAddress(this.address.getHostAddress(), this.port); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanException.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanException.java deleted file mode 100644 index 5585fc49d416..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanException.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012-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.boot.web.context; - -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.web.server.WebServerFactory; - -/** - * Exception thrown when there is no {@link WebServerFactory} bean of the required type - * defined in a {@link WebServerApplicationContext}. - * - * @author Guirong Hu - * @author Andy Wilkinson - * @since 2.7.0 - */ -public class MissingWebServerFactoryBeanException extends NoSuchBeanDefinitionException { - - private final WebApplicationType webApplicationType; - - /** - * Create a new {@code MissingWebServerFactoryBeanException}. - * @param webServerApplicationContextClass the class of the - * WebServerApplicationContext that required the WebServerFactory - * @param webServerFactoryClass the class of the WebServerFactory that was missing - * @param webApplicationType the type of the web application - */ - public MissingWebServerFactoryBeanException( - Class webServerApplicationContextClass, - Class webServerFactoryClass, WebApplicationType webApplicationType) { - super(webServerFactoryClass, String.format("Unable to start %s due to missing %s bean", - webServerApplicationContextClass.getSimpleName(), webServerFactoryClass.getSimpleName())); - this.webApplicationType = webApplicationType; - } - - /** - * Returns the type of web application for which a {@link WebServerFactory} bean was - * missing. - * @return the type of web application - */ - public WebApplicationType getWebApplicationType() { - return this.webApplicationType; - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzer.java deleted file mode 100644 index d27cdd786130..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzer.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012-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.boot.web.context; - -import java.util.Locale; - -import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; -import org.springframework.boot.diagnostics.FailureAnalysis; -import org.springframework.boot.diagnostics.FailureAnalyzer; -import org.springframework.core.annotation.Order; - -/** - * A {@link FailureAnalyzer} that performs analysis of failures caused by a - * {@link MissingWebServerFactoryBeanException}. - * - * @author Guirong Hu - * @author Andy Wilkinson - */ -@Order(0) -class MissingWebServerFactoryBeanFailureAnalyzer extends AbstractFailureAnalyzer { - - @Override - protected FailureAnalysis analyze(Throwable rootFailure, MissingWebServerFactoryBeanException cause) { - return new FailureAnalysis( - "Web application could not be started as there was no " + cause.getBeanType().getName() - + " bean defined in the context.", - "Check your application's dependencies for a supported " - + cause.getWebApplicationType().name().toLowerCase(Locale.ENGLISH) + " web server.\n" - + "Check the configured web application type.", - cause); - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactory.java index 223058f7202a..531667de61a1 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyReactiveWebServerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -236,7 +236,7 @@ private Handler applyWrapper(Handler handler, HandlerWrapper wrapper) { } private void customizeSsl(Server server, InetSocketAddress address) { - new SslServerCustomizer(address, getSsl(), getOrCreateSslStoreProvider(), getHttp2()).customize(server); + new SslServerCustomizer(address, getSsl(), getSslStoreProvider(), getHttp2()).customize(server); } } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java index 40f3ba7cf0cd..cf28b85c2f08 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java @@ -220,7 +220,7 @@ private Handler applyWrapper(Handler handler, HandlerWrapper wrapper) { } private void customizeSsl(Server server, InetSocketAddress address) { - new SslServerCustomizer(address, getSsl(), getOrCreateSslStoreProvider(), getHttp2()).customize(server); + new SslServerCustomizer(address, getSsl(), getSslStoreProvider(), getHttp2()).customize(server); } /** diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyReactiveWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyReactiveWebServerFactory.java index ae14a41c331c..78170a4ddf40 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyReactiveWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/NettyReactiveWebServerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -179,8 +179,7 @@ private HttpServer createHttpServer() { @SuppressWarnings("deprecation") private HttpServer customizeSslConfiguration(HttpServer httpServer) { - SslServerCustomizer sslServerCustomizer = new SslServerCustomizer(getSsl(), getHttp2(), - getOrCreateSslStoreProvider()); + SslServerCustomizer sslServerCustomizer = new SslServerCustomizer(getSsl(), getHttp2(), getSslStoreProvider()); return sslServerCustomizer.apply(httpServer); } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactory.java index 6a76e0be7bc2..ca4a48a83c8e 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactory.java @@ -221,7 +221,7 @@ private void customizeProtocol(AbstractProtocol protocol) { } private void customizeSsl(Connector connector) { - new SslConnectorCustomizer(getSsl(), getOrCreateSslStoreProvider()).customize(connector); + new SslConnectorCustomizer(getSsl(), getSslStoreProvider()).customize(connector); } @Override diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java index 2f3eda5b2b8d..ff31364eb222 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java @@ -360,7 +360,7 @@ private void invokeProtocolHandlerCustomizers(ProtocolHandler protocolHandler) { } private void customizeSsl(Connector connector) { - new SslConnectorCustomizer(getSsl(), getOrCreateSslStoreProvider()).customize(connector); + new SslConnectorCustomizer(getSsl(), getSslStoreProvider()).customize(connector); } /** diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowWebServerFactoryDelegate.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowWebServerFactoryDelegate.java index dc7482d4860e..0b17e7a908c3 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowWebServerFactoryDelegate.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowWebServerFactoryDelegate.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -163,8 +163,7 @@ Builder createBuilder(AbstractConfigurableWebServerFactory factory) { builder.setServerOption(UndertowOptions.ENABLE_HTTP2, http2.isEnabled()); } if (ssl != null && ssl.isEnabled()) { - new SslBuilderCustomizer(factory.getPort(), address, ssl, factory.getOrCreateSslStoreProvider()) - .customize(builder); + new SslBuilderCustomizer(factory.getPort(), address, ssl, factory.getSslStoreProvider()).customize(builder); } else { builder.addHttpListener(port, (address != null) ? address.getHostAddress() : "0.0.0.0"); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContext.java index f21b87e392db..5a088e802fc7 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -18,11 +18,9 @@ import org.springframework.beans.BeansException; import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.boot.WebApplicationType; import org.springframework.boot.availability.AvailabilityChangeEvent; import org.springframework.boot.availability.ReadinessState; import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext; -import org.springframework.boot.web.context.MissingWebServerFactoryBeanException; import org.springframework.boot.web.context.WebServerGracefulShutdownLifecycle; import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; import org.springframework.boot.web.server.WebServer; @@ -107,8 +105,8 @@ protected String getWebServerFactoryBeanName() { // Use bean names so that we don't consider the hierarchy String[] beanNames = getBeanFactory().getBeanNamesForType(ReactiveWebServerFactory.class); if (beanNames.length == 0) { - throw new MissingWebServerFactoryBeanException(getClass(), ReactiveWebServerFactory.class, - WebApplicationType.REACTIVE); + throw new ApplicationContextException( + "Unable to start ReactiveWebApplicationContext due to missing ReactiveWebServerFactory bean."); } if (beanNames.length > 1) { throw new ApplicationContextException("Unable to start ReactiveWebApplicationContext due to multiple " diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java index f821882ddd54..9e825504d0c1 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -100,10 +100,7 @@ private Map getErrorAttributes(ServerRequest request, boolean in private HttpStatus determineHttpStatus(Throwable error, MergedAnnotation responseStatusAnnotation) { if (error instanceof ResponseStatusException) { - HttpStatus httpStatus = HttpStatus.resolve(((ResponseStatusException) error).getStatusCode().value()); - if (httpStatus != null) { - return httpStatus; - } + return ((ResponseStatusException) error).getStatus(); } return responseStatusAnnotation.getValue("code", HttpStatus.class).orElse(HttpStatus.INTERNAL_SERVER_ERROR); } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/ReactiveWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/ReactiveWebServerFactory.java index 101137d06498..94f1b701aa82 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/ReactiveWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/server/ReactiveWebServerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -17,7 +17,6 @@ package org.springframework.boot.web.reactive.server; import org.springframework.boot.web.server.WebServer; -import org.springframework.boot.web.server.WebServerFactory; import org.springframework.http.server.reactive.HttpHandler; /** @@ -28,7 +27,7 @@ * @see WebServer */ @FunctionalInterface -public interface ReactiveWebServerFactory extends WebServerFactory { +public interface ReactiveWebServerFactory { /** * Gets a new fully configured but paused {@link WebServer} instance. Clients should diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/AbstractConfigurableWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/AbstractConfigurableWebServerFactory.java index 1cde582ced0f..fb29b31e0910 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/AbstractConfigurableWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/AbstractConfigurableWebServerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2020 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. @@ -36,7 +36,6 @@ * @author Ivan Sopov * @author Eddú Meléndez * @author Brian Clozel - * @author Scott Frederick * @since 2.0.0 */ public abstract class AbstractConfigurableWebServerFactory implements ConfigurableWebServerFactory { @@ -180,18 +179,6 @@ public Shutdown getShutdown() { return this.shutdown; } - /** - * Return the provided {@link SslStoreProvider} or create one using {@link Ssl} - * properties. - * @return the {@code SslStoreProvider} - */ - public final SslStoreProvider getOrCreateSslStoreProvider() { - if (this.sslStoreProvider != null) { - return this.sslStoreProvider; - } - return CertificateFileSslStoreProvider.from(this.ssl); - } - /** * Return the absolute temp dir for given web server. * @param prefix server name diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/CertificateFileSslStoreProvider.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/CertificateFileSslStoreProvider.java deleted file mode 100644 index 56480fb8f383..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/CertificateFileSslStoreProvider.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2012-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.boot.web.server; - -import java.io.IOException; -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.PrivateKey; -import java.security.cert.X509Certificate; - -/** - * An {@link SslStoreProvider} that creates key and trust stores from certificate and - * private key PEM files. - * - * @author Scott Frederick - * @since 2.7.0 - */ -public final class CertificateFileSslStoreProvider implements SslStoreProvider { - - private static final char[] NO_PASSWORD = {}; - - private static final String DEFAULT_KEY_ALIAS = "spring-boot-web"; - - private final Ssl ssl; - - private CertificateFileSslStoreProvider(Ssl ssl) { - this.ssl = ssl; - } - - @Override - public KeyStore getKeyStore() throws Exception { - return createKeyStore(this.ssl.getCertificate(), this.ssl.getCertificatePrivateKey(), - this.ssl.getKeyStorePassword(), this.ssl.getKeyStoreType(), this.ssl.getKeyAlias()); - } - - @Override - public KeyStore getTrustStore() throws Exception { - if (this.ssl.getTrustCertificate() == null) { - return null; - } - return createKeyStore(this.ssl.getTrustCertificate(), this.ssl.getTrustCertificatePrivateKey(), - this.ssl.getTrustStorePassword(), this.ssl.getTrustStoreType(), this.ssl.getKeyAlias()); - } - - /** - * Create a new {@link KeyStore} populated with the certificate stored at the - * specified file path and an optional private key. - * @param certPath the path to the certificate authority file - * @param keyPath the path to the private file - * @param password the key store password - * @param storeType the {@code KeyStore} type to create - * @param keyAlias the alias to use when adding keys to the {@code KeyStore} - * @return the {@code KeyStore} - */ - private KeyStore createKeyStore(String certPath, String keyPath, String password, String storeType, - String keyAlias) { - try { - KeyStore keyStore = KeyStore.getInstance((storeType != null) ? storeType : KeyStore.getDefaultType()); - keyStore.load(null); - X509Certificate[] certificates = CertificateParser.parse(certPath); - PrivateKey privateKey = (keyPath != null) ? PrivateKeyParser.parse(keyPath) : null; - try { - addCertificates(keyStore, certificates, privateKey, password, keyAlias); - } - catch (KeyStoreException ex) { - throw new IllegalStateException("Error adding certificates to KeyStore: " + ex.getMessage(), ex); - } - return keyStore; - } - catch (GeneralSecurityException | IOException ex) { - throw new IllegalStateException("Error creating KeyStore: " + ex.getMessage(), ex); - } - } - - private void addCertificates(KeyStore keyStore, X509Certificate[] certificates, PrivateKey privateKey, - String password, String keyAlias) throws KeyStoreException { - String alias = (keyAlias != null) ? keyAlias : DEFAULT_KEY_ALIAS; - if (privateKey != null) { - keyStore.setKeyEntry(alias, privateKey, ((password != null) ? password.toCharArray() : NO_PASSWORD), - certificates); - } - else { - for (int index = 0; index < certificates.length; index++) { - keyStore.setCertificateEntry(alias + "-" + index, certificates[index]); - } - } - } - - /** - * Create a {@link SslStoreProvider} if the appropriate SSL properties are configured. - * @param ssl the SSL properties - * @return a {@code SslStoreProvider} or {@code null} - */ - public static SslStoreProvider from(Ssl ssl) { - if (ssl != null && ssl.isEnabled()) { - if (ssl.getCertificate() != null && ssl.getCertificatePrivateKey() != null) { - return new CertificateFileSslStoreProvider(ssl); - } - } - return null; - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/CertificateParser.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/CertificateParser.java deleted file mode 100644 index 11867b095fbe..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/CertificateParser.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2012-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.boot.web.server; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URL; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.springframework.util.Base64Utils; -import org.springframework.util.FileCopyUtils; -import org.springframework.util.ResourceUtils; - -/** - * Parser for X.509 certificates in PEM format. - * - * @author Scott Frederick - * @author Phillip Webb - */ -final class CertificateParser { - - private static final String HEADER = "-+BEGIN\\s+.*CERTIFICATE[^-]*-+(?:\\s|\\r|\\n)+"; - - private static final String BASE64_TEXT = "([a-z0-9+/=\\r\\n]+)"; - - private static final String FOOTER = "-+END\\s+.*CERTIFICATE[^-]*-+"; - - private static final Pattern PATTERN = Pattern.compile(HEADER + BASE64_TEXT + FOOTER, Pattern.CASE_INSENSITIVE); - - private CertificateParser() { - } - - /** - * Load certificates from the specified resource. - * @param path the certificate to parse - * @return the parsed certificates - */ - static X509Certificate[] parse(String path) { - CertificateFactory factory = getCertificateFactory(); - List certificates = new ArrayList<>(); - readCertificates(path, factory, certificates::add); - return certificates.toArray(new X509Certificate[0]); - } - - private static CertificateFactory getCertificateFactory() { - try { - return CertificateFactory.getInstance("X.509"); - } - catch (CertificateException ex) { - throw new IllegalStateException("Unable to get X.509 certificate factory", ex); - } - } - - private static void readCertificates(String resource, CertificateFactory factory, - Consumer consumer) { - try { - String text = readText(resource); - Matcher matcher = PATTERN.matcher(text); - while (matcher.find()) { - String encodedText = matcher.group(1); - byte[] decodedBytes = decodeBase64(encodedText); - ByteArrayInputStream inputStream = new ByteArrayInputStream(decodedBytes); - while (inputStream.available() > 0) { - consumer.accept((X509Certificate) factory.generateCertificate(inputStream)); - } - } - } - catch (CertificateException | IOException ex) { - throw new IllegalStateException("Error reading certificate from '" + resource + "' : " + ex.getMessage(), - ex); - } - } - - private static String readText(String resource) throws IOException { - URL url = ResourceUtils.getURL(resource); - try (Reader reader = new InputStreamReader(url.openStream())) { - return FileCopyUtils.copyToString(reader); - } - } - - private static byte[] decodeBase64(String content) { - byte[] bytes = content.replaceAll("\r", "").replaceAll("\n", "").getBytes(); - return Base64Utils.decode(bytes); - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/LocalServerPort.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/LocalServerPort.java index c522d48d0afc..07d2e2893c81 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/LocalServerPort.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/LocalServerPort.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -28,8 +28,6 @@ * Annotation at the field or method/constructor parameter level that injects the HTTP * port that got allocated at runtime. Provides a convenient alternative for * @Value("${local.server.port}"). - * @deprecated since 2.7.0 for removal in 2.9.0 in favor or - * {@code org.springframework.boot.test.web.server.LocalServerPort} * * @author Anand Shah * @author Stephane Nicoll @@ -39,7 +37,6 @@ @Retention(RetentionPolicy.RUNTIME) @Documented @Value("${local.server.port}") -@Deprecated public @interface LocalServerPort { } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PrivateKeyParser.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PrivateKeyParser.java deleted file mode 100644 index 924653d12528..000000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PrivateKeyParser.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2012-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.boot.web.server; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URL; -import java.security.GeneralSecurityException; -import java.security.KeyFactory; -import java.security.PrivateKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.springframework.util.Base64Utils; -import org.springframework.util.FileCopyUtils; -import org.springframework.util.ResourceUtils; - -/** - * Parser for PKCS private key files in PEM format. - * - * @author Scott Frederick - * @author Phillip Webb - */ -final class PrivateKeyParser { - - private static final String PKCS1_HEADER = "-+BEGIN\\s+RSA\\s+PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+"; - - private static final String PKCS1_FOOTER = "-+END\\s+RSA\\s+PRIVATE\\s+KEY[^-]*-+"; - - private static final String PKCS8_FOOTER = "-+END\\s+PRIVATE\\s+KEY[^-]*-+"; - - private static final String PKCS8_HEADER = "-+BEGIN\\s+PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+"; - - private static final String BASE64_TEXT = "([a-z0-9+/=\\r\\n]+)"; - - private static final Pattern PKCS1_PATTERN = Pattern.compile(PKCS1_HEADER + BASE64_TEXT + PKCS1_FOOTER, - Pattern.CASE_INSENSITIVE); - - private static final Pattern PKCS8_KEY_PATTERN = Pattern.compile(PKCS8_HEADER + BASE64_TEXT + PKCS8_FOOTER, - Pattern.CASE_INSENSITIVE); - - private PrivateKeyParser() { - } - - /** - * Load a private key from the specified resource. - * @param resource the private key to parse - * @return the parsed private key - */ - static PrivateKey parse(String resource) { - try { - String text = readText(resource); - Matcher matcher = PKCS1_PATTERN.matcher(text); - if (matcher.find()) { - return parsePkcs1(decodeBase64(matcher.group(1))); - } - matcher = PKCS8_KEY_PATTERN.matcher(text); - if (matcher.find()) { - return parsePkcs8(decodeBase64(matcher.group(1))); - } - throw new IllegalStateException("Unrecognized private key format in " + resource); - } - catch (GeneralSecurityException | IOException ex) { - throw new IllegalStateException("Error loading private key file " + resource, ex); - } - } - - private static PrivateKey parsePkcs1(byte[] privateKeyBytes) throws GeneralSecurityException { - byte[] pkcs8Bytes = convertPkcs1ToPkcs8(privateKeyBytes); - return parsePkcs8(pkcs8Bytes); - } - - private static byte[] convertPkcs1ToPkcs8(byte[] pkcs1) { - try { - ByteArrayOutputStream result = new ByteArrayOutputStream(); - int pkcs1Length = pkcs1.length; - int totalLength = pkcs1Length + 22; - // Sequence + total length - result.write(bytes(0x30, 0x82)); - result.write((totalLength >> 8) & 0xff); - result.write(totalLength & 0xff); - // Integer (0) - result.write(bytes(0x02, 0x01, 0x00)); - // Sequence: 1.2.840.113549.1.1.1, NULL - result.write( - bytes(0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00)); - // Octet string + length - result.write(bytes(0x04, 0x82)); - result.write((pkcs1Length >> 8) & 0xff); - result.write(pkcs1Length & 0xff); - // PKCS1 - result.write(pkcs1); - return result.toByteArray(); - } - catch (IOException ex) { - throw new IllegalStateException(ex); - } - } - - private static byte[] bytes(int... elements) { - byte[] result = new byte[elements.length]; - for (int i = 0; i < elements.length; i++) { - result[i] = (byte) elements[i]; - } - return result; - } - - private static PrivateKey parsePkcs8(byte[] privateKeyBytes) throws GeneralSecurityException { - try { - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes); - KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - return keyFactory.generatePrivate(keySpec); - } - catch (InvalidKeySpecException ex) { - throw new IllegalArgumentException("Unexpected key format", ex); - } - } - - private static String readText(String resource) throws IOException { - URL url = ResourceUtils.getURL(resource); - try (Reader reader = new InputStreamReader(url.openStream())) { - return FileCopyUtils.copyToString(reader); - } - } - - private static byte[] decodeBase64(String content) { - byte[] contentBytes = content.replaceAll("\r", "").replaceAll("\n", "").getBytes(); - return Base64Utils.decode(contentBytes); - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Ssl.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Ssl.java index af4400717c7c..8d1da04391e3 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Ssl.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Ssl.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -22,7 +22,6 @@ * @author Andy Wilkinson * @author Vladimir Tsanev * @author Stephane Nicoll - * @author Scott Frederick * @since 2.0.0 */ public class Ssl { @@ -55,14 +54,6 @@ public class Ssl { private String trustStoreProvider; - private String certificate; - - private String certificatePrivateKey; - - private String trustCertificate; - - private String trustCertificatePrivateKey; - private String protocol = "TLS"; /** @@ -235,54 +226,6 @@ public void setTrustStoreProvider(String trustStoreProvider) { this.trustStoreProvider = trustStoreProvider; } - /** - * Return the location of the certificate in PEM format. - * @return the certificate location - */ - public String getCertificate() { - return this.certificate; - } - - public void setCertificate(String certificate) { - this.certificate = certificate; - } - - /** - * Return the location of the private key for the certificate in PEM format. - * @return the location of the certificate private key - */ - public String getCertificatePrivateKey() { - return this.certificatePrivateKey; - } - - public void setCertificatePrivateKey(String certificatePrivateKey) { - this.certificatePrivateKey = certificatePrivateKey; - } - - /** - * Return the location of the trust certificate authority chain in PEM format. - * @return the location of the trust certificate - */ - public String getTrustCertificate() { - return this.trustCertificate; - } - - public void setTrustCertificate(String trustCertificate) { - this.trustCertificate = trustCertificate; - } - - /** - * Return the location of the private key for the trust certificate in PEM format. - * @return the location of the trust certificate private key - */ - public String getTrustCertificatePrivateKey() { - return this.trustCertificatePrivateKey; - } - - public void setTrustCertificatePrivateKey(String trustCertificatePrivateKey) { - this.trustCertificatePrivateKey = trustCertificatePrivateKey; - } - /** * Return the SSL protocol to use. * @return the SSL protocol diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java index d69f67280b0e..9da658ccc9bd 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java @@ -36,11 +36,9 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.Scope; import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.boot.WebApplicationType; import org.springframework.boot.availability.AvailabilityChangeEvent; import org.springframework.boot.availability.ReadinessState; import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext; -import org.springframework.boot.web.context.MissingWebServerFactoryBeanException; import org.springframework.boot.web.context.WebServerGracefulShutdownLifecycle; import org.springframework.boot.web.server.WebServer; import org.springframework.boot.web.servlet.FilterRegistrationBean; @@ -208,8 +206,8 @@ protected ServletWebServerFactory getWebServerFactory() { // Use bean names so that we don't consider the hierarchy String[] beanNames = getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class); if (beanNames.length == 0) { - throw new MissingWebServerFactoryBeanException(getClass(), ServletWebServerFactory.class, - WebApplicationType.SERVLET); + throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing " + + "ServletWebServerFactory bean."); } if (beanNames.length > 1) { throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple " diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/ServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/ServletWebServerFactory.java index 062148af6a95..b1bea96c44fa 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/ServletWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/server/ServletWebServerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -17,7 +17,6 @@ package org.springframework.boot.web.servlet.server; import org.springframework.boot.web.server.WebServer; -import org.springframework.boot.web.server.WebServerFactory; import org.springframework.boot.web.servlet.ServletContextInitializer; /** @@ -28,7 +27,7 @@ * @see WebServer */ @FunctionalInterface -public interface ServletWebServerFactory extends WebServerFactory { +public interface ServletWebServerFactory { /** * Gets a new fully configured but paused {@link WebServer} instance. Clients should diff --git a/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories index 937fc54c794c..95f7013b783b 100644 --- a/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories @@ -74,7 +74,6 @@ org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFa org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer,\ org.springframework.boot.diagnostics.analyzer.PatternParseFailureAnalyzer,\ org.springframework.boot.liquibase.LiquibaseChangelogMissingFailureAnalyzer,\ -org.springframework.boot.web.context.MissingWebServerFactoryBeanFailureAnalyzer,\ org.springframework.boot.web.embedded.tomcat.ConnectorStartFailureAnalyzer # Failure Analysis Reporters diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ExitCodeGeneratorsTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ExitCodeGeneratorsTests.java index 051278528375..9a81e7162653 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ExitCodeGeneratorsTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ExitCodeGeneratorsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -21,13 +21,10 @@ import org.junit.jupiter.api.Test; -import org.springframework.core.Ordered; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.withSettings; /** * Tests for {@link ExitCodeGenerators}. @@ -65,9 +62,18 @@ void getExitCodeWhenGeneratorThrowsShouldReturnOne() { } @Test - void getExitCodeWithUnorderedGeneratorsReturnsFirstNonZeroExitCode() { + void getExitCodeWhenAllNegativeShouldReturnLowestValue() { + ExitCodeGenerators generators = new ExitCodeGenerators(); + generators.add(mockGenerator(-1)); + generators.add(mockGenerator(-3)); + generators.add(mockGenerator(-2)); + assertThat(generators.getExitCode()).isEqualTo(-3); + } + + @Test + void getExitCodeWhenAllPositiveShouldReturnHighestValue() { ExitCodeGenerators generators = new ExitCodeGenerators(); - generators.add(mockGenerator(0)); + generators.add(mockGenerator(1)); generators.add(mockGenerator(3)); generators.add(mockGenerator(2)); assertThat(generators.getExitCode()).isEqualTo(3); @@ -83,29 +89,12 @@ void getExitCodeWhenUsingExitCodeExceptionMapperShouldCallMapper() { assertThat(generators.getExitCode()).isEqualTo(2); } - @Test - void getExitCodeWithOrderedGeneratorsReturnsFirstNonZeroExitCode() { - ExitCodeGenerators generators = new ExitCodeGenerators(); - generators.add(orderedMockGenerator(0, 1)); - generators.add(orderedMockGenerator(1, 3)); - generators.add(orderedMockGenerator(2, 2)); - generators.add(mockGenerator(3)); - assertThat(generators.getExitCode()).isEqualTo(2); - } - private ExitCodeGenerator mockGenerator(int exitCode) { ExitCodeGenerator generator = mock(ExitCodeGenerator.class); given(generator.getExitCode()).willReturn(exitCode); return generator; } - private ExitCodeGenerator orderedMockGenerator(int exitCode, int order) { - ExitCodeGenerator generator = mock(ExitCodeGenerator.class, withSettings().extraInterfaces(Ordered.class)); - given(generator.getExitCode()).willReturn(exitCode); - given(((Ordered) generator).getOrder()).willReturn(order); - return generator; - } - private ExitCodeExceptionMapper mockMapper(Class exceptionType, int exitCode) { return (exception) -> { if (exceptionType.isInstance(exception)) { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringBootVersionTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringBootVersionTests.java index 887413c25ca4..9e6995b3b557 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringBootVersionTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringBootVersionTests.java @@ -31,7 +31,7 @@ * * @author Andy Wilkinson */ -class SpringBootVersionTests { +public class SpringBootVersionTests { @Test void getVersionShouldReturnVersionMatchingGradleProperties() throws IOException { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesBeanTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesBeanTests.java index 3fad65e03a42..a11250b39d19 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesBeanTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesBeanTests.java @@ -78,15 +78,6 @@ void getAllReturnsAll() { } } - @Test - void getAllDoesNotFindABeanDeclaredInAStaticBeanMethodOnAConfigurationAndConfigurationPropertiesAnnotatedClass() { - try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( - StaticBeanMethodConfiguration.class)) { - Map all = ConfigurationPropertiesBean.getAll(context); - assertThat(all).containsOnlyKeys("configurationPropertiesBeanTests.StaticBeanMethodConfiguration"); - } - } - @Test void getAllWhenHasBadBeanDoesNotFail() { try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( @@ -613,18 +604,6 @@ class Inner { class ParameterizedConstructorInner { ParameterizedConstructorInner(Integer age) { - - } - - } - - @Configuration(proxyBeanMethods = false) - @ConfigurationProperties - static class StaticBeanMethodConfiguration { - - @Bean - static String stringBean() { - return "example"; } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/BeanCurrentlyInCreationFailureAnalyzerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/BeanCurrentlyInCreationFailureAnalyzerTests.java index ba6f4f6e5ca6..3324acb57118 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/BeanCurrentlyInCreationFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/BeanCurrentlyInCreationFailureAnalyzerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -43,14 +43,10 @@ * Tests for {@link BeanCurrentlyInCreationFailureAnalyzer}. * * @author Andy Wilkinson - * @author Scott Frederick */ class BeanCurrentlyInCreationFailureAnalyzerTests { - private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - - private final BeanCurrentlyInCreationFailureAnalyzer analyzer = new BeanCurrentlyInCreationFailureAnalyzer( - this.context.getBeanFactory()); + private final BeanCurrentlyInCreationFailureAnalyzer analyzer = new BeanCurrentlyInCreationFailureAnalyzer(); @Test void cyclicBeanMethods() throws IOException { @@ -135,13 +131,13 @@ void cycleWithAnUnknownStartIsNotAnalyzed() { } @Test - void cycleWithCircularReferencesAllowed() { + void cycleWithCircularReferencesAllowed() throws IOException { FailureAnalysis analysis = performAnalysis(CyclicBeanMethodsConfiguration.class, true); assertThat(analysis.getAction()).contains("Despite circular references being allowed"); } @Test - void cycleWithCircularReferencesProhibited() { + void cycleWithCircularReferencesProhibited() throws IOException { FailureAnalysis analysis = performAnalysis(CyclicBeanMethodsConfiguration.class, false); assertThat(analysis.getAction()).contains("As a last resort"); } @@ -163,12 +159,13 @@ private FailureAnalysis performAnalysis(Class configuration, boolean allowCir } private Exception createFailure(Class configuration, boolean allowCircularReferences) { - try { - this.context.register(configuration); - AbstractAutowireCapableBeanFactory beanFactory = (AbstractAutowireCapableBeanFactory) this.context + try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) { + context.register(configuration); + AbstractAutowireCapableBeanFactory beanFactory = (AbstractAutowireCapableBeanFactory) context .getBeanFactory(); + this.analyzer.setBeanFactory(beanFactory); beanFactory.setAllowCircularReferences(allowCircularReferences); - this.context.refresh(); + context.refresh(); fail("Expected failure did not occur"); return null; } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/InvalidConfigurationPropertyValueFailureAnalyzerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/InvalidConfigurationPropertyValueFailureAnalyzerTests.java index f8cf1a3e2be7..45d47f6e5abc 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/InvalidConfigurationPropertyValueFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/InvalidConfigurationPropertyValueFailureAnalyzerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -34,7 +34,6 @@ * Tests for {@link InvalidConfigurationPropertyValueFailureAnalyzer}. * * @author Stephane Nicoll - * @author Scott Frederick */ class InvalidConfigurationPropertyValueFailureAnalyzerTests { @@ -44,7 +43,7 @@ class InvalidConfigurationPropertyValueFailureAnalyzerTests { void analysisWithNullEnvironment() { InvalidConfigurationPropertyValueException failure = new InvalidConfigurationPropertyValueException( "test.property", "invalid", "This is not valid."); - FailureAnalysis analysis = new InvalidConfigurationPropertyValueFailureAnalyzer(null).analyze(failure); + FailureAnalysis analysis = new InvalidConfigurationPropertyValueFailureAnalyzer().analyze(failure); assertThat(analysis).isNull(); } @@ -107,8 +106,8 @@ private void assertCommonParts(InvalidConfigurationPropertyValueException failur } private FailureAnalysis performAnalysis(InvalidConfigurationPropertyValueException failure) { - InvalidConfigurationPropertyValueFailureAnalyzer analyzer = new InvalidConfigurationPropertyValueFailureAnalyzer( - this.environment); + InvalidConfigurationPropertyValueFailureAnalyzer analyzer = new InvalidConfigurationPropertyValueFailureAnalyzer(); + analyzer.setEnvironment(this.environment); return analyzer.analyze(failure); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/MutuallyExclusiveConfigurationPropertiesFailureAnalyzerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/MutuallyExclusiveConfigurationPropertiesFailureAnalyzerTests.java index a81645e36f9c..04e373a18c41 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/MutuallyExclusiveConfigurationPropertiesFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/MutuallyExclusiveConfigurationPropertiesFailureAnalyzerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -39,7 +39,6 @@ * Tests for {@link MutuallyExclusiveConfigurationPropertiesFailureAnalyzer}. * * @author Andy Wilkinson - * @author Scott Frederick */ class MutuallyExclusiveConfigurationPropertiesFailureAnalyzerTests { @@ -50,7 +49,7 @@ void analyzeWhenEnvironmentIsNullShouldReturnNull() { MutuallyExclusiveConfigurationPropertiesException failure = new MutuallyExclusiveConfigurationPropertiesException( new HashSet<>(Arrays.asList("com.example.a", "com.example.b")), new HashSet<>(Arrays.asList("com.example.a", "com.example.b"))); - FailureAnalysis failureAnalysis = new MutuallyExclusiveConfigurationPropertiesFailureAnalyzer(null) + FailureAnalysis failureAnalysis = new MutuallyExclusiveConfigurationPropertiesFailureAnalyzer() .analyze(failure); assertThat(failureAnalysis).isNull(); } @@ -113,8 +112,8 @@ void analyzeWhenPropertyIsInMultiplePropertySourcesShouldListEachSourceInAnalysi } private FailureAnalysis performAnalysis(MutuallyExclusiveConfigurationPropertiesException failure) { - MutuallyExclusiveConfigurationPropertiesFailureAnalyzer analyzer = new MutuallyExclusiveConfigurationPropertiesFailureAnalyzer( - this.environment); + MutuallyExclusiveConfigurationPropertiesFailureAnalyzer analyzer = new MutuallyExclusiveConfigurationPropertiesFailureAnalyzer(); + analyzer.setEnvironment(this.environment); return analyzer.analyze(failure); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzerTests.java index b14fcaa76dd4..aebbab4bbbad 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -36,14 +36,10 @@ * Tests for {@link NoUniqueBeanDefinitionFailureAnalyzer}. * * @author Andy Wilkinson - * @author Scott Frederick */ class NoUniqueBeanDefinitionFailureAnalyzerTests { - private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - - private final NoUniqueBeanDefinitionFailureAnalyzer analyzer = new NoUniqueBeanDefinitionFailureAnalyzer( - this.context.getBeanFactory()); + private final NoUniqueBeanDefinitionFailureAnalyzer analyzer = new NoUniqueBeanDefinitionFailureAnalyzer(); @Test void failureAnalysisForFieldConsumer() { @@ -94,15 +90,18 @@ void failureAnalysisForObjectProviderConstructorConsumer() { } private BeanCreationException createFailure(Class consumer) { - this.context.register(DuplicateBeansProducer.class, consumer); - this.context.setParent(new AnnotationConfigApplicationContext(ParentProducer.class)); - try { - this.context.refresh(); - } - catch (BeanCreationException ex) { - return ex; + try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) { + context.register(DuplicateBeansProducer.class, consumer); + context.setParent(new AnnotationConfigApplicationContext(ParentProducer.class)); + try { + context.refresh(); + } + catch (BeanCreationException ex) { + this.analyzer.setBeanFactory(context.getBeanFactory()); + return ex; + } + return null; } - return null; } private FailureAnalysis analyzeFailure(BeanCreationException failure) { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/context/LocalRSocketServerPortTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/context/LocalRSocketServerPortTests.java index 55852ba1f1ef..452a7d8e1d3e 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/context/LocalRSocketServerPortTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/context/LocalRSocketServerPortTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -32,7 +32,6 @@ * @author Verónica Vásquez * @author Eddú Meléndez */ -@Deprecated @ExtendWith(SpringExtension.class) @TestPropertySource(properties = "local.rsocket.server.port=8181") class LocalRSocketServerPortTests { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactoryTests.java index 4c739922fd98..0a79bea42861 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/rsocket/netty/NettyRSocketServerFactoryTests.java @@ -64,7 +64,6 @@ * @author Brian Clozel * @author Leo Li * @author Chris Bono - * @author Scott Frederick */ class NettyRSocketServerFactoryTests { @@ -167,30 +166,6 @@ void websocketTransportBasicSslFromFileSystem() { testBasicSslWithKeyStore("src/test/resources/test.jks", "password", Transport.WEBSOCKET); } - @Test - void tcpTransportBasicSslCertificateFromClassPath() { - testBasicSslWithPemCertificate("classpath:test-cert.pem", "classpath:test-key.pem", "classpath:test-cert.pem", - Transport.TCP); - } - - @Test - void tcpTransportBasicSslCertificateFromFileSystem() { - testBasicSslWithPemCertificate("src/test/resources/test-cert.pem", "src/test/resources/test-key.pem", - "src/test/resources/test-cert.pem", Transport.TCP); - } - - @Test - void websocketTransportBasicSslCertificateFromClassPath() { - testBasicSslWithPemCertificate("classpath:test-cert.pem", "classpath:test-key.pem", "classpath:test-cert.pem", - Transport.WEBSOCKET); - } - - @Test - void websocketTransportBasicSslCertificateFromFileSystem() { - testBasicSslWithPemCertificate("src/test/resources/test-cert.pem", "src/test/resources/test-key.pem", - "src/test/resources/test-cert.pem", Transport.WEBSOCKET); - } - private void checkEchoRequest() { String payload = "test payload"; Mono response = this.requester.route("test").data(payload).retrieveMono(String.class); @@ -211,23 +186,6 @@ private void testBasicSslWithKeyStore(String keyStore, String keyPassword, Trans checkEchoRequest(); } - private void testBasicSslWithPemCertificate(String certificate, String certificatePrivateKey, - String trustCertificate, Transport transport) { - NettyRSocketServerFactory factory = getFactory(); - factory.setTransport(transport); - Ssl ssl = new Ssl(); - ssl.setCertificate(certificate); - ssl.setCertificatePrivateKey(certificatePrivateKey); - ssl.setTrustCertificate(trustCertificate); - ssl.setKeyStorePassword(""); - factory.setSsl(ssl); - this.server = factory.create(new EchoRequestResponseAcceptor()); - this.server.start(); - this.requester = (transport == Transport.TCP) ? createSecureRSocketTcpClient() - : createSecureRSocketWebSocketClient(); - checkEchoRequest(); - } - @Test void tcpTransportSslRejectsInsecureClient() { NettyRSocketServerFactory factory = getFactory(); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzerTests.java deleted file mode 100644 index fb30be29caf4..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/context/MissingWebServerFactoryBeanFailureAnalyzerTests.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2012-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.boot.web.context; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.diagnostics.FailureAnalysis; -import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext; -import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; -import org.springframework.context.ApplicationContextException; -import org.springframework.context.ConfigurableApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link MissingWebServerFactoryBeanFailureAnalyzer}. - * - * @author Guirong Hu - * @author Andy Wilkinson - */ -class MissingWebServerFactoryBeanFailureAnalyzerTests { - - @Test - void missingServletWebServerFactoryBeanFailure() { - ApplicationContextException failure = createFailure(new ServletWebServerApplicationContext()); - assertThat(failure).isNotNull(); - FailureAnalysis analysis = new MissingWebServerFactoryBeanFailureAnalyzer().analyze(failure); - assertThat(analysis).isNotNull(); - assertThat(analysis.getDescription()).isEqualTo("Web application could not be started as there was no " - + ServletWebServerFactory.class.getName() + " bean defined in the context."); - assertThat(analysis.getAction()).isEqualTo( - "Check your application's dependencies for a supported servlet web server.\nCheck the configured web " - + "application type."); - } - - @Test - void missingReactiveWebServerFactoryBeanFailure() { - ApplicationContextException failure = createFailure(new ReactiveWebServerApplicationContext()); - FailureAnalysis analysis = new MissingWebServerFactoryBeanFailureAnalyzer().analyze(failure); - assertThat(analysis).isNotNull(); - assertThat(analysis.getDescription()).isEqualTo("Web application could not be started as there was no " - + ReactiveWebServerFactory.class.getName() + " bean defined in the context."); - assertThat(analysis.getAction()).isEqualTo( - "Check your application's dependencies for a supported reactive web server.\nCheck the configured web " - + "application type."); - } - - private ApplicationContextException createFailure(ConfigurableApplicationContext context) { - try { - context.refresh(); - context.close(); - return null; - } - catch (ApplicationContextException ex) { - return ex; - } - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java index dc103519a9ea..d467117edc41 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java @@ -27,7 +27,6 @@ import java.util.HashMap; import java.util.Locale; import java.util.Map; -import java.util.Properties; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicReference; @@ -81,8 +80,6 @@ import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory; import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactoryTests; import org.springframework.core.io.ByteArrayResource; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.support.PropertiesLoaderUtils; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -407,15 +404,13 @@ protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) { } @Test - void defaultLocaleCharsetMappingsAreOverridden() throws IOException { + void defaultLocaleCharsetMappingsAreOverridden() { TomcatServletWebServerFactory factory = getFactory(); this.webServer = factory.getWebServer(); // override defaults, see org.apache.catalina.util.CharsetMapperDefault.properties - Properties charsetMapperDefault = PropertiesLoaderUtils - .loadProperties(new ClassPathResource("CharsetMapperDefault.properties", CharsetMapper.class)); - for (String language : charsetMapperDefault.stringPropertyNames()) { - assertThat(getCharset(new Locale(language))).isEqualTo(StandardCharsets.UTF_8); - } + assertThat(getCharset(Locale.ENGLISH)).isEqualTo(StandardCharsets.UTF_8); + assertThat(getCharset(Locale.FRENCH)).isEqualTo(StandardCharsets.UTF_8); + assertThat(getCharset(Locale.JAPANESE)).isEqualTo(StandardCharsets.UTF_8); } @Test diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContextTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContextTests.java index 13ae884265cc..24ff9da399ab 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContextTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContextTests.java @@ -61,7 +61,7 @@ void cleanUp() { void whenThereIsNoWebServerFactoryBeanThenContextRefreshWillFail() { assertThatExceptionOfType(ApplicationContextException.class).isThrownBy(() -> this.context.refresh()) .withMessageContaining( - "Unable to start ReactiveWebServerApplicationContext due to missing ReactiveWebServerFactory bean"); + "Unable to start ReactiveWebApplicationContext due to missing ReactiveWebServerFactory bean"); } @Test diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java index 96b9d93fb153..e694b1c89dcd 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java @@ -86,7 +86,6 @@ * Base for testing classes that extends {@link AbstractReactiveWebServerFactory}. * * @author Brian Clozel - * @author Scott Frederick */ public abstract class AbstractReactiveWebServerFactoryTests { @@ -216,7 +215,7 @@ void sslWantsClientAuthenticationSucceedsWithClientCertificate() throws Exceptio ssl.setKeyPassword("password"); ssl.setKeyStorePassword("secret"); ssl.setTrustStore("classpath:test.jks"); - testClientAuthSuccess(ssl, buildTrustAllSslWithClientKeyConnector("test.jks", "password")); + testClientAuthSuccess(ssl, buildTrustAllSslWithClientKeyConnector()); } @Test @@ -230,15 +229,14 @@ void sslWantsClientAuthenticationSucceedsWithoutClientCertificate() { testClientAuthSuccess(ssl, buildTrustAllSslConnector()); } - protected ReactorClientHttpConnector buildTrustAllSslWithClientKeyConnector(String keyStoreFile, - String keyStorePassword) throws Exception { + protected ReactorClientHttpConnector buildTrustAllSslWithClientKeyConnector() throws Exception { KeyStore clientKeyStore = KeyStore.getInstance(KeyStore.getDefaultType()); - try (InputStream stream = new FileInputStream("src/test/resources/" + keyStoreFile)) { + try (InputStream stream = new FileInputStream("src/test/resources/test.jks")) { clientKeyStore.load(stream, "secret".toCharArray()); } KeyManagerFactory clientKeyManagerFactory = KeyManagerFactory .getInstance(KeyManagerFactory.getDefaultAlgorithm()); - clientKeyManagerFactory.init(clientKeyStore, keyStorePassword.toCharArray()); + clientKeyManagerFactory.init(clientKeyStore, "password".toCharArray()); Http11SslContextSpec sslContextSpec = Http11SslContextSpec.forClient() .configure((builder) -> builder.sslProvider(SslProvider.JDK) @@ -267,7 +265,7 @@ void sslNeedsClientAuthenticationSucceedsWithClientCertificate() throws Exceptio ssl.setKeyStorePassword("secret"); ssl.setKeyPassword("password"); ssl.setTrustStore("classpath:test.jks"); - testClientAuthSuccess(ssl, buildTrustAllSslWithClientKeyConnector("test.jks", "password")); + testClientAuthSuccess(ssl, buildTrustAllSslWithClientKeyConnector()); } @Test @@ -281,17 +279,6 @@ void sslNeedsClientAuthenticationFailsWithoutClientCertificate() { testClientAuthFailure(ssl, buildTrustAllSslConnector()); } - @Test - void sslWithPemCertificates() throws Exception { - Ssl ssl = new Ssl(); - ssl.setClientAuth(Ssl.ClientAuth.NEED); - ssl.setCertificate("classpath:test-cert.pem"); - ssl.setCertificatePrivateKey("classpath:test-key.pem"); - ssl.setTrustCertificate("classpath:test-cert.pem"); - ssl.setKeyStorePassword("secret"); - testClientAuthSuccess(ssl, buildTrustAllSslWithClientKeyConnector("test.p12", "secret")); - } - protected void testClientAuthFailure(Ssl sslConfiguration, ReactorClientHttpConnector clientConnector) { AbstractReactiveWebServerFactory factory = getFactory(); factory.setSsl(sslConfiguration); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CertificateFileSslStoreProviderTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CertificateFileSslStoreProviderTests.java deleted file mode 100644 index 8f0fcdd6626e..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CertificateFileSslStoreProviderTests.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2012-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.boot.web.server; - -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link CertificateFileSslStoreProvider}. - * - * @author Scott Frederick - */ -class CertificateFileSslStoreProviderTests { - - @Test - void fromSslWhenNullReturnsNull() { - assertThat(CertificateFileSslStoreProvider.from(null)).isNull(); - } - - @Test - void fromSslWhenDisabledReturnsNull() { - assertThat(CertificateFileSslStoreProvider.from(new Ssl())).isNull(); - } - - @Test - void fromSslWithCertAndKeyReturnsStoreProvider() throws Exception { - Ssl ssl = new Ssl(); - ssl.setEnabled(true); - ssl.setCertificate("classpath:test-cert.pem"); - ssl.setCertificatePrivateKey("classpath:test-key.pem"); - SslStoreProvider storeProvider = CertificateFileSslStoreProvider.from(ssl); - assertThat(storeProvider).isNotNull(); - assertStoreContainsCertAndKey(storeProvider.getKeyStore(), KeyStore.getDefaultType(), "spring-boot-web"); - assertThat(storeProvider.getTrustStore()).isNull(); - } - - @Test - void fromSslWithCertAndKeyAndTrustCertReturnsStoreProvider() throws Exception { - Ssl ssl = new Ssl(); - ssl.setEnabled(true); - ssl.setCertificate("classpath:test-cert.pem"); - ssl.setCertificatePrivateKey("classpath:test-key.pem"); - ssl.setTrustCertificate("classpath:test-cert.pem"); - SslStoreProvider storeProvider = CertificateFileSslStoreProvider.from(ssl); - assertThat(storeProvider).isNotNull(); - assertStoreContainsCertAndKey(storeProvider.getKeyStore(), KeyStore.getDefaultType(), "spring-boot-web"); - assertStoreContainsCert(storeProvider.getTrustStore(), KeyStore.getDefaultType(), "spring-boot-web-0"); - } - - @Test - void fromSslWithCertAndKeyAndTrustCertAndTrustKeyReturnsStoreProvider() throws Exception { - Ssl ssl = new Ssl(); - ssl.setEnabled(true); - ssl.setCertificate("classpath:test-cert.pem"); - ssl.setCertificatePrivateKey("classpath:test-key.pem"); - ssl.setTrustCertificate("classpath:test-cert.pem"); - ssl.setTrustCertificatePrivateKey("classpath:test-key.pem"); - SslStoreProvider storeProvider = CertificateFileSslStoreProvider.from(ssl); - assertThat(storeProvider).isNotNull(); - assertStoreContainsCertAndKey(storeProvider.getKeyStore(), KeyStore.getDefaultType(), "spring-boot-web"); - assertStoreContainsCertAndKey(storeProvider.getTrustStore(), KeyStore.getDefaultType(), "spring-boot-web"); - } - - @Test - void fromSslWithKeyAliasReturnsStoreProvider() throws Exception { - Ssl ssl = new Ssl(); - ssl.setEnabled(true); - ssl.setKeyAlias("test-alias"); - ssl.setCertificate("classpath:test-cert.pem"); - ssl.setCertificatePrivateKey("classpath:test-key.pem"); - ssl.setTrustCertificate("classpath:test-cert.pem"); - ssl.setTrustCertificatePrivateKey("classpath:test-key.pem"); - SslStoreProvider storeProvider = CertificateFileSslStoreProvider.from(ssl); - assertThat(storeProvider).isNotNull(); - assertStoreContainsCertAndKey(storeProvider.getKeyStore(), KeyStore.getDefaultType(), "test-alias"); - assertStoreContainsCertAndKey(storeProvider.getTrustStore(), KeyStore.getDefaultType(), "test-alias"); - } - - @Test - void fromSslWithStoreTypeReturnsStoreProvider() throws Exception { - Ssl ssl = new Ssl(); - ssl.setEnabled(true); - ssl.setKeyStoreType("PKCS12"); - ssl.setTrustStoreType("PKCS12"); - ssl.setCertificate("classpath:test-cert.pem"); - ssl.setCertificatePrivateKey("classpath:test-key.pem"); - ssl.setTrustCertificate("classpath:test-cert.pem"); - ssl.setTrustCertificatePrivateKey("classpath:test-key.pem"); - SslStoreProvider storeProvider = CertificateFileSslStoreProvider.from(ssl); - assertThat(storeProvider).isNotNull(); - assertStoreContainsCertAndKey(storeProvider.getKeyStore(), "PKCS12", "spring-boot-web"); - assertStoreContainsCertAndKey(storeProvider.getTrustStore(), "PKCS12", "spring-boot-web"); - } - - private void assertStoreContainsCertAndKey(KeyStore keyStore, String keyStoreType, String keyAlias) - throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { - assertThat(keyStore).isNotNull(); - assertThat(keyStore.getType()).isEqualTo(keyStoreType); - assertThat(keyStore.containsAlias(keyAlias)).isTrue(); - assertThat(keyStore.getCertificate(keyAlias)).isNotNull(); - assertThat(keyStore.getKey(keyAlias, new char[] {})).isNotNull(); - } - - private void assertStoreContainsCert(KeyStore keyStore, String keyStoreType, String keyAlias) - throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { - assertThat(keyStore).isNotNull(); - assertThat(keyStore.getType()).isEqualTo(keyStoreType); - assertThat(keyStore.containsAlias(keyAlias)).isTrue(); - assertThat(keyStore.getCertificate(keyAlias)).isNotNull(); - assertThat(keyStore.getKey(keyAlias, new char[] {})).isNull(); - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CertificateParserTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CertificateParserTests.java deleted file mode 100644 index 7107c1ae7b59..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/CertificateParserTests.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-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.boot.web.server; - -import java.security.cert.X509Certificate; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; - -/** - * Tests for {@link CertificateParser}. - * - * @author Scott Frederick - */ -class CertificateParserTests { - - @Test - void parseCertificate() { - X509Certificate[] certificates = CertificateParser.parse("classpath:test-cert.pem"); - assertThat(certificates).isNotNull(); - assertThat(certificates.length).isEqualTo(1); - assertThat(certificates[0].getType()).isEqualTo("X.509"); - } - - @Test - void parseCertificateChain() { - X509Certificate[] certificates = CertificateParser.parse("classpath:test-cert-chain.pem"); - assertThat(certificates).isNotNull(); - assertThat(certificates.length).isEqualTo(2); - assertThat(certificates[0].getType()).isEqualTo("X.509"); - assertThat(certificates[1].getType()).isEqualTo("X.509"); - } - - @Test - void parseWithInvalidPathWillThrowException() { - String path = "file:///bad/path/cert.pem"; - assertThatIllegalStateException().isThrownBy(() -> CertificateParser.parse("file:///bad/path/cert.pem")) - .withMessageContaining(path); - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/LocalServerPortTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/LocalServerPortTests.java index 3c5004bc21bd..da6fd5c2cc17 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/LocalServerPortTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/LocalServerPortTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -32,7 +32,6 @@ * @author Anand Shah * @author Phillip Webb */ -@Deprecated @ExtendWith(SpringExtension.class) @TestPropertySource(properties = "local.server.port=8181") class LocalServerPortTests { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/PrivateKeyParserTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/PrivateKeyParserTests.java deleted file mode 100644 index 0a55581ea915..000000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/PrivateKeyParserTests.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012-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.boot.web.server; - -import java.security.PrivateKey; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; - -/** - * Tests for {@link PrivateKeyParser}. - * - * @author Scott Frederick - */ -class PrivateKeyParserTests { - - @Test - void parsePkcs8KeyFile() { - PrivateKey privateKey = PrivateKeyParser.parse("classpath:test-key.pem"); - assertThat(privateKey).isNotNull(); - assertThat(privateKey.getFormat()).isEqualTo("PKCS#8"); - } - - @Test - void parseWithNonKeyFileWillThrowException() { - String path = "classpath:test-banner.txt"; - assertThatIllegalStateException().isThrownBy(() -> PrivateKeyParser.parse("file://" + path)) - .withMessageContaining(path); - } - - @Test - void parseWithInvalidPathWillThrowException() { - String path = "file:///bad/path/key.pem"; - assertThatIllegalStateException().isThrownBy(() -> PrivateKeyParser.parse(path)).withMessageContaining(path); - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactoryTests.java index 321edb55cd3f..690b66a93f8a 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/server/AbstractServletWebServerFactoryTests.java @@ -167,7 +167,6 @@ * @author Greg Turnquist * @author Andy Wilkinson * @author Raja Kolli - * @author Scott Frederick */ @ExtendWith(OutputCaptureExtension.class) public abstract class AbstractServletWebServerFactoryTests { @@ -560,23 +559,6 @@ void pkcs12KeyStoreAndTrustStore() throws Exception { assertThat(getResponse(getLocalUrl("https", "/test.txt"), requestFactory)).isEqualTo("test"); } - @Test - void pemKeyStoreAndTrustStore() throws Exception { - AbstractServletWebServerFactory factory = getFactory(); - addTestTxtFile(factory); - factory.setSsl(getSsl("classpath:test-cert.pem", "classpath:test-key.pem")); - this.webServer = factory.getWebServer(); - this.webServer.start(); - KeyStore keyStore = KeyStore.getInstance("pkcs12"); - loadStore(keyStore, new FileSystemResource("src/test/resources/test.p12")); - SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( - new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy()) - .loadKeyMaterial(keyStore, "secret".toCharArray()).build()); - HttpClient httpClient = this.httpClientBuilder.get().setSSLSocketFactory(socketFactory).build(); - HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); - assertThat(getResponse(getLocalUrl("https", "/test.txt"), requestFactory)).isEqualTo("test"); - } - @Test void sslNeedsClientAuthenticationSucceedsWithClientCertificate() throws Exception { AbstractServletWebServerFactory factory = getFactory(); @@ -728,16 +710,6 @@ private Ssl getSsl(ClientAuth clientAuth, String keyPassword, String keyAlias, S return ssl; } - private Ssl getSsl(String cert, String privateKey) { - Ssl ssl = new Ssl(); - ssl.setClientAuth(ClientAuth.NEED); - ssl.setCertificate(cert); - ssl.setCertificatePrivateKey(privateKey); - ssl.setTrustCertificate(cert); - ssl.setKeyStorePassword("secret"); - return ssl; - } - protected void testRestrictedSSLProtocolsAndCipherSuites(String[] protocols, String[] ciphers) throws Exception { AbstractServletWebServerFactory factory = getFactory(); factory.setSsl(getSsl(null, "password", "src/test/resources/restricted.jks", null, protocols, ciphers)); diff --git a/spring-boot-project/spring-boot/src/test/resources/test-cert-chain.pem b/spring-boot-project/spring-boot/src/test/resources/test-cert-chain.pem deleted file mode 100644 index df103772cfe2..000000000000 --- a/spring-boot-project/spring-boot/src/test/resources/test-cert-chain.pem +++ /dev/null @@ -1,32 +0,0 @@ ------BEGIN TRUSTED CERTIFICATE----- -MIIClzCCAgACCQCPbjkRoMVEQDANBgkqhkiG9w0BAQUFADCBjzELMAkGA1UEBhMC -VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28x -DTALBgNVBAoMBFRlc3QxDTALBgNVBAsMBFRlc3QxFDASBgNVBAMMC2V4YW1wbGUu -Y29tMR8wHQYJKoZIhvcNAQkBFhB0ZXN0QGV4YW1wbGUuY29tMB4XDTIwMDMyNzIx -NTgwNFoXDTIxMDMyNzIxNTgwNFowgY8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApD -YWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ0wCwYDVQQKDARUZXN0 -MQ0wCwYDVQQLDARUZXN0MRQwEgYDVQQDDAtleGFtcGxlLmNvbTEfMB0GCSqGSIb3 -DQEJARYQdGVzdEBleGFtcGxlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC -gYEA1YzixWEoyzrd20C2R1gjyPCoPfFLlG6UYTyT0tueNy6yjv6qbJ8lcZg7616O -3I9LuOHhZh9U+fCDCgPfiDdyJfDEW/P+dsOMFyMUXPrJPze2yPpOnvV8iJ5DM93u -fEVhCCyzLdYu0P2P3hU2W+T3/Im9DA7FOPA2vF1SrIJ2qtUCAwEAATANBgkqhkiG -9w0BAQUFAAOBgQBdShkwUv78vkn1jAdtfbB+7mpV9tufVdo29j7pmotTCz3ny5fc -zLEfeu6JPugAR71JYbc2CqGrMneSk1zT91EH6ohIz8OR5VNvzB7N7q65Ci7OFMPl -ly6k3rHpMCBtHoyNFhNVfPLxGJ9VlWFKLgIAbCmL4OIQm1l6Fr1MSM38Zw== ------END TRUSTED CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICjzCCAfgCAQEwDQYJKoZIhvcNAQEFBQAwgY8xCzAJBgNVBAYTAlVTMRMwEQYD -VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ0wCwYDVQQK -DARUZXN0MQ0wCwYDVQQLDARUZXN0MRQwEgYDVQQDDAtleGFtcGxlLmNvbTEfMB0G -CSqGSIb3DQEJARYQdGVzdEBleGFtcGxlLmNvbTAeFw0yMDAzMjcyMjAxNDZaFw0y -MTAzMjcyMjAxNDZaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5p -YTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwEVGVzdDENMAsGA1UE -CwwEVGVzdDEUMBIGA1UEAwwLZXhhbXBsZS5jb20xHzAdBgkqhkiG9w0BCQEWEHRl -c3RAZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM7kd2cj -F49wm1+OQ7Q5GE96cXueWNPr/Nwei71tf6G4BmE0B+suXHEvnLpHTj9pdX/ZzBIK -8jIZ/x8RnSduK/Ky+zm1QMYUWZtWCAgCW8WzgB69Cn/hQG8KSX3S9bqODuQAvP54 -GQJD7+4kVuNBGjFb4DaD4nvMmPtALSZf8ZCZAgMBAAEwDQYJKoZIhvcNAQEFBQAD -gYEAOn6X8+0VVlDjF+TvTgI0KIasA6nDm+KXe7LVtfvqWqQZH4qyd2uiwcDM3Aux -a/OsPdOw0j+NqFDBd3mSMhSVgfvXdK6j9WaxY1VGXyaidLARgvn63wfzgr857sQW -c8eSxbwEQxwlMvVxW6Os4VhCfUQr8VrBrvPa2zs+6IlK+Ug= ------END CERTIFICATE----- \ No newline at end of file diff --git a/spring-boot-project/spring-boot/src/test/resources/test-cert.pem b/spring-boot-project/spring-boot/src/test/resources/test-cert.pem deleted file mode 100644 index 1e912b9f6399..000000000000 --- a/spring-boot-project/spring-boot/src/test/resources/test-cert.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICpDCCAYwCCQCDOqHKPjAhCTANBgkqhkiG9w0BAQUFADAUMRIwEAYDVQQDDAls -b2NhbGhvc3QwHhcNMTQwOTEwMjE0MzA1WhcNMTQxMDEwMjE0MzA1WjAUMRIwEAYD -VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDR -0KfxUw7MF/8RB5/YXOM7yLnoHYb/M/6dyoulMbtEdKKhQhU28o5FiDkHcEG9PJQL -gqrRgAjl3VmCC9omtfZJQ2EpfkTttkJjnKOOroXhYE51/CYSckapBYCVh8GkjUEJ -uEfnp07cTfYZFqViIgIWPZyjkzl3w4girS7kCuzNdDntVJVx5F/EsFwMA8n3C0Qa -zHQoM5s00Fer6aTwd6AW0JD5QkADavpfzZ554e4HrVGwHlM28WKQQkFzzGu44FFX -yVuEF3HeyVPug8GRHAc8UU7ijVgJB5TmbvRGYowIErD5i4VvGLuOv9mgR3aVyN0S -dJ1N7aJnXpeSQjAgf03jAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAE4yvwhbPldg -Bpl7sBw/m2B3bfiNeSqa4tII1PQ7ysgWVb9HbFNKkriScwDWlqo6ljZfJ+SDFCoj -bQz4fOFdMAOzRnpTrG2NAKMoJLY0/g/p7XO00PiC8T3h3BOJ5SHuW3gUyfGXmAYs -DnJxJOrwPzj57xvNXjNSbDOJ3DRfCbB0CWBexOeGDiUokoEq3Gnz04Q4ZfHyAcpZ -3deMw8Od5p9WAoCh3oClpFyOSzXYKZd+3ppMMtfc4wnbfocnfSFxj0UCpOEJw4Ez -+lGuHKdhNOVW9CmqPD1y76o6c8PQKuF7KZEoY2jvy3GeIfddBvqXgZ4PbWvFz1jO -32C9XWHwRA4= ------END CERTIFICATE----- diff --git a/spring-boot-project/spring-boot/src/test/resources/test-key.pem b/spring-boot-project/spring-boot/src/test/resources/test-key.pem deleted file mode 100644 index 00d439edc6b0..000000000000 --- a/spring-boot-project/spring-boot/src/test/resources/test-key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDR0KfxUw7MF/8R -B5/YXOM7yLnoHYb/M/6dyoulMbtEdKKhQhU28o5FiDkHcEG9PJQLgqrRgAjl3VmC -C9omtfZJQ2EpfkTttkJjnKOOroXhYE51/CYSckapBYCVh8GkjUEJuEfnp07cTfYZ -FqViIgIWPZyjkzl3w4girS7kCuzNdDntVJVx5F/EsFwMA8n3C0QazHQoM5s00Fer -6aTwd6AW0JD5QkADavpfzZ554e4HrVGwHlM28WKQQkFzzGu44FFXyVuEF3HeyVPu -g8GRHAc8UU7ijVgJB5TmbvRGYowIErD5i4VvGLuOv9mgR3aVyN0SdJ1N7aJnXpeS -QjAgf03jAgMBAAECggEBAIhQyzwj3WJGWOZkkLqOpufJotcmj/Wwf0VfOdkq9WMl -cB/bAlN/xWVxerPVgDCFch4EWBzi1WUaqbOvJZ2u7QNubmr56aiTmJCFTVI/GyZx -XqiTGN01N6lKtN7xo6LYTyAUhUsBTWAemrx0FSErvTVb9C/mUBj6hbEZ2XQ5kN5t -7qYX4Lu0zyn7s1kX5SLtm5I+YRq7HSwB6wLy+DSroO71izZ/VPwME3SwT5SN+c87 -3dkklR7fumNd9dOpSWKrLPnq4aMko00rvIGc63xD1HrEpXUkB5v24YEn7HwCLEH7 -b8jrp79j2nCvvR47inpf+BR8FIWAHEOUUqCEzjQkdiECgYEA6ifjMM0f02KPeIs7 -zXd1lI7CUmJmzkcklCIpEbKWf/t/PHv3QgqIkJzERzRaJ8b+GhQ4zrSwAhrGUmI8 -kDkXIqe2/2ONgIOX2UOHYHyTDQZHnlXyDecvHUTqs2JQZCGBZkXyZ9i0j3BnTymC -iZ8DvEa0nxsbP+U3rgzPQmXiQVMCgYEA5WN2Y/RndbriNsNrsHYRldbPO5nfV9rp -cDzcQU66HRdK5VIdbXT9tlMYCJIZsSqE0tkOwTgEB/sFvF/tIHSCY5iO6hpIyk6g -kkUzPcld4eM0dEPAge7SYUbakB9CMvA7MkDQSXQNFyZ0mH83+UikwT6uYHFh7+ox -N1P+psDhXzECgYEA1gXLVQnIcy/9LxMkgDMWV8j8uMyUZysDthpbK3/uq+A2dhRg -9g4msPd5OBQT65OpIjElk1n4HpRWfWqpLLHiAZ0GWPynk7W0D7P3gyuaRSdeQs0P -x8FtgPVDCN9t13gAjHiWjnC26Py2kNbCKAQeJ/MAmQTvrUFX2VCACJKTcV0CgYAj -xJWSUmrLfb+GQISLOG3Xim434e9keJsLyEGj4U29+YLRLTOvfJ2PD3fg5j8hU/rw -Ea5uTHi8cdTcIa0M8X3fX8txD3YoLYh2JlouGTcNYOst8d6TpBSj3HN6I5Wj8beZ -R2fy/CiKYpGtsbCdq0kdZNO18BgQW9kewncjs1GxEQKBgQCf8q34h6KuHpHSDh9h -YkDTypk0FReWBAVJCzDNDUMhVLFivjcwtaMd2LiC3FMKZYodr52iKg60cj43vbYI -frmFFxoL37rTmUocCTBKc0LhWj6MicI+rcvQYe1uwTrpWdFf1aZJMYRLRczeKtev -OWaE/9hVZ5+9pild1NukGpOydw== ------END PRIVATE KEY----- diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CustomServletPathSampleActuatorTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CustomServletPathSampleActuatorTests.java index 9bccb2246a5b..21c55cf772af 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CustomServletPathSampleActuatorTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CustomServletPathSampleActuatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2020 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. @@ -18,7 +18,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.core.env.Environment; /** diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortAndPathSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortAndPathSampleActuatorApplicationTests.java index 9c24a3270848..7365b5a5b129 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortAndPathSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortAndPathSampleActuatorApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2020 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. @@ -19,11 +19,11 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortCustomServletPathSampleActuatorTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortCustomServletPathSampleActuatorTests.java index ce2fb6f68b80..d8fb11a4eed1 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortCustomServletPathSampleActuatorTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortCustomServletPathSampleActuatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -19,10 +19,10 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/SampleActuatorCustomSecurityApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/SampleActuatorCustomSecurityApplicationTests.java index 221c7daab86a..841e9c964636 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/SampleActuatorCustomSecurityApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/SampleActuatorCustomSecurityApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -22,7 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-ui/src/test/java/smoketest/actuator/ui/SampleActuatorUiApplicationPortTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-ui/src/test/java/smoketest/actuator/ui/SampleActuatorUiApplicationPortTests.java index 878c403c4cb9..c8009a6a5c06 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-ui/src/test/java/smoketest/actuator/ui/SampleActuatorUiApplicationPortTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-ui/src/test/java/smoketest/actuator/ui/SampleActuatorUiApplicationPortTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -20,11 +20,11 @@ import org.junit.jupiter.api.Test; +import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/AbstractManagementPortAndPathSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/AbstractManagementPortAndPathSampleActuatorApplicationTests.java index 79bd73ce278c..ac9e1b5bb0ec 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/AbstractManagementPortAndPathSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/AbstractManagementPortAndPathSampleActuatorApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -21,9 +21,9 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementAddressActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementAddressActuatorApplicationTests.java index 6e9a137baa7c..298ea9f80d0b 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementAddressActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementAddressActuatorApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2020 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. @@ -20,11 +20,11 @@ import org.junit.jupiter.api.Test; +import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java index 9e3b73ac5106..d4885013374e 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementDifferentPortSampleActuatorApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -18,9 +18,9 @@ import org.junit.jupiter.api.Test; +import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortSampleActuatorApplicationTests.java index 20a86d394af0..f69f1001c9ca 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortSampleActuatorApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -22,12 +22,12 @@ import smoketest.actuator.ManagementPortSampleActuatorApplicationTests.CustomErrorAttributes; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.error.ErrorAttributeOptions; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortWithLazyInitializationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortWithLazyInitializationTests.java index 301befa38164..518f05fad711 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortWithLazyInitializationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementPortWithLazyInitializationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -18,9 +18,9 @@ import org.junit.jupiter.api.Test; +import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-client/src/test/java/smoketest/oauth2/client/SampleOAuth2ClientApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-client/src/test/java/smoketest/oauth2/client/SampleOAuth2ClientApplicationTests.java index e8ab5308e939..6ce6e5efb06f 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-client/src/test/java/smoketest/oauth2/client/SampleOAuth2ClientApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-oauth2-client/src/test/java/smoketest/oauth2/client/SampleOAuth2ClientApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -23,7 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-profile/src/test/java/smoketest/profile/ActiveProfilesTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-profile/src/test/java/smoketest/profile/ActiveProfilesTests.java index e116c52bbedd..51a66ee2bd00 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-profile/src/test/java/smoketest/profile/ActiveProfilesTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-profile/src/test/java/smoketest/profile/ActiveProfilesTests.java @@ -33,7 +33,8 @@ * * @author Madhura Bhave */ -@SpringBootTest(webEnvironment = WebEnvironment.NONE, properties = { "enableEnvironmentPostProcessor=true" }) // gh-28530 +@SpringBootTest(webEnvironment = WebEnvironment.NONE, + properties = { "enableEnvironmentPostProcessor=true", "server.port=0" }) // gh-28530 @ActiveProfiles("hello") class ActiveProfilesTests { diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-rsocket/src/test/java/smoketest/rsocket/SampleRSocketApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-rsocket/src/test/java/smoketest/rsocket/SampleRSocketApplicationTests.java index 97a5899cbd18..a3bab71de4bc 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-rsocket/src/test/java/smoketest/rsocket/SampleRSocketApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-rsocket/src/test/java/smoketest/rsocket/SampleRSocketApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -23,8 +23,8 @@ import reactor.test.StepVerifier; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.rsocket.context.LocalRSocketServerPort; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.rsocket.server.LocalRSocketServerPort; import org.springframework.messaging.rsocket.RSocketRequester; import org.springframework.security.rsocket.metadata.SimpleAuthenticationEncoder; import org.springframework.security.rsocket.metadata.UsernamePasswordMetadata; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/main/resources/application.yml b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/main/resources/application.yml index 83ac8e90b398..4256d2d331c1 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/main/resources/application.yml +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/main/resources/application.yml @@ -8,10 +8,10 @@ spring: credentials: - private-key-location: "classpath:saml/privatekey.txt" certificate-location: "classpath:saml/certificate.txt" - asserting-party: + identityprovider: verification: credentials: - - certificate-location: "classpath:saml/certificate.txt" + - certificate-location: "classpath:saml/certificate.txt" entity-id: simplesaml singlesignon: url: https://simplesaml-for-spring-saml/SSOService.php @@ -21,10 +21,10 @@ spring: credentials: - private-key-location: "classpath:saml/privatekey.txt" certificate-location: "classpath:saml/certificate.txt" - asserting-party: + identityprovider: verification: credentials: - - certificate-location: "classpath:saml/certificate.txt" + - certificate-location: "classpath:saml/certificate.txt" entity-id: okta-id-1234 singlesignon: url: diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/test/java/smoketest/saml2/serviceprovider/SampleSaml2RelyingPartyApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/test/java/smoketest/saml2/serviceprovider/SampleSaml2RelyingPartyApplicationTests.java index 7250bc1afc48..b38cd2896b65 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/test/java/smoketest/saml2/serviceprovider/SampleSaml2RelyingPartyApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-saml2-service-provider/src/test/java/smoketest/saml2/serviceprovider/SampleSaml2RelyingPartyApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -23,7 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -46,7 +46,7 @@ void everythingShouldRedirectToLogin() { } @Test - void loginShouldHaveAllAssertingPartiesToChooseFrom() { + void loginShouldHaveAllIdentityProvidersToChooseFrom() { ResponseEntity entity = this.restTemplate.getForEntity("/login", String.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(entity.getBody()).contains("/saml2/authenticate/simplesamlphp"); diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/ManagementPortSampleSecureWebFluxTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/ManagementPortSampleSecureWebFluxTests.java index a0cebf047dc6..e338be7593ac 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/ManagementPortSampleSecureWebFluxTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/ManagementPortSampleSecureWebFluxTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -22,12 +22,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.autoconfigure.security.reactive.EndpointRequest; +import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.actuate.web.mappings.MappingsEndpoint; import org.springframework.boot.autoconfigure.security.reactive.PathRequest; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.web.server.ServerHttpSecurity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/test/java/smoketest/session/redis/SampleSessionRedisApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/test/java/smoketest/session/redis/SampleSessionRedisApplicationTests.java index eca768c384ee..8863197968bf 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/test/java/smoketest/session/redis/SampleSessionRedisApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-redis/src/test/java/smoketest/session/redis/SampleSessionRedisApplicationTests.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.Map; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -61,7 +60,6 @@ static void applicationProperties(DynamicPropertyRegistry registry) { } @Test - @Disabled("See gh-30673") @SuppressWarnings("unchecked") void sessionsEndpointShouldReturnUserSessions() { createSession(URI.create("/")); diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux/src/test/java/smoketest/session/SampleSessionWebFluxApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux/src/test/java/smoketest/session/SampleSessionWebFluxApplicationTests.java index f19abfcfba14..d7238c9fc607 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux/src/test/java/smoketest/session/SampleSessionWebFluxApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux/src/test/java/smoketest/session/SampleSessionWebFluxApplicationTests.java @@ -25,8 +25,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.testsupport.junit.DisabledOnOs; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.web.reactive.function.client.WebClient; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-multi-connectors/src/test/java/smoketest/tomcat/multiconnector/SampleTomcatTwoConnectorsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-multi-connectors/src/test/java/smoketest/tomcat/multiconnector/SampleTomcatTwoConnectorsApplicationTests.java index 590bddf8238a..83ecd7e19993 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-multi-connectors/src/test/java/smoketest/tomcat/multiconnector/SampleTomcatTwoConnectorsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-tomcat-multi-connectors/src/test/java/smoketest/tomcat/multiconnector/SampleTomcatTwoConnectorsApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -26,10 +26,10 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.context.WebServerInitializedEvent; import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/build.gradle deleted file mode 100644 index 077f6cd415ee..000000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/build.gradle +++ /dev/null @@ -1,13 +0,0 @@ -plugins { - id "java" - id "org.springframework.boot.conventions" -} - -description = "Spring Boot web application type smoke test" - -dependencies { - implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) - implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-webflux")) - - testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) -} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/main/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplication.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/main/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplication.java deleted file mode 100644 index 6d836ae1bd92..000000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/main/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplication.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2012-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 smoketest.webapplicationtype; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class SampleWebApplicationTypeApplication { - - public static void main(String[] args) { - SpringApplication.run(SampleWebApplicationTypeApplication.class, args); - } - -} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/main/resources/application.properties b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/main/resources/application.properties deleted file mode 100644 index a8cc36cc0a56..000000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -spring.main.web-application-type=reactive diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/OverriddenWebApplicationTypeApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/OverriddenWebApplicationTypeApplicationTests.java deleted file mode 100644 index 217f7faeb9ec..000000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/OverriddenWebApplicationTypeApplicationTests.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2012-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 smoketest.webapplicationtype; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.ApplicationContext; -import org.springframework.web.context.WebApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for an application using an overridden web application type - * - * @author Andy Wilkinson - */ -@SpringBootTest(properties = "spring.main.web-application-type=servlet") -class OverriddenWebApplicationTypeApplicationTests { - - @Autowired - private ApplicationContext context; - - @Test - void contextIsServlet() { - assertThat(this.context).isInstanceOf(WebApplicationContext.class); - } - -} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplicationTests.java deleted file mode 100644 index a3fabb10ef1e..000000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/SampleWebApplicationTypeApplicationTests.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2012-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 smoketest.webapplicationtype; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; -import org.springframework.context.ApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for an application using a configured web application type - * - * @author Andy Wilkinson - */ -@SpringBootTest -class SampleWebApplicationTypeApplicationTests { - - @Autowired - private ApplicationContext context; - - @Test - void contextIsReactive() { - assertThat(this.context).isInstanceOf(ReactiveWebApplicationContext.class); - } - -} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/WebEnvironmentNoneOverridesWebApplicationTypeTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/WebEnvironmentNoneOverridesWebApplicationTypeTests.java deleted file mode 100644 index c3275a9944a3..000000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-application-type/src/test/java/smoketest/webapplicationtype/WebEnvironmentNoneOverridesWebApplicationTypeTests.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2012-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 smoketest.webapplicationtype; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; -import org.springframework.context.ApplicationContext; -import org.springframework.web.context.WebApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for a web environment of none overriding the configured web - * application type. - * - * @author Andy Wilkinson - */ -@SpringBootTest(webEnvironment = WebEnvironment.NONE) -class WebEnvironmentNoneOverridesWebApplicationTypeTests { - - @Autowired - private ApplicationContext context; - - @Test - void contextIsPlain() { - assertThat(this.context).isNotInstanceOf(ReactiveWebApplicationContext.class); - assertThat(this.context).isNotInstanceOf(WebApplicationContext.class); - } - -} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-groovy-templates/src/test/java/smoketest/groovytemplates/SampleGroovyTemplateApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-groovy-templates/src/test/java/smoketest/groovytemplates/SampleGroovyTemplateApplicationTests.java index a52c86691ae3..be72ca9e134b 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-groovy-templates/src/test/java/smoketest/groovytemplates/SampleGroovyTemplateApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-groovy-templates/src/test/java/smoketest/groovytemplates/SampleGroovyTemplateApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -24,7 +24,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.util.LinkedMultiValueMap; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/test/java/smoketest/security/method/SampleMethodSecurityApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/test/java/smoketest/security/method/SampleMethodSecurityApplicationTests.java index c84ea18c9344..79147ca0ab18 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/test/java/smoketest/security/method/SampleMethodSecurityApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-method-security/src/test/java/smoketest/security/method/SampleMethodSecurityApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -24,7 +24,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-custom/src/test/java/smoketest/web/secure/custom/SampleWebSecureCustomApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-custom/src/test/java/smoketest/web/secure/custom/SampleWebSecureCustomApplicationTests.java index 5580a3ce55e7..6fabfa8e7bc5 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-custom/src/test/java/smoketest/web/secure/custom/SampleWebSecureCustomApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-custom/src/test/java/smoketest/web/secure/custom/SampleWebSecureCustomApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -24,7 +24,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-jdbc/src/test/java/smoketest/web/secure/jdbc/SampleWebSecureJdbcApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-jdbc/src/test/java/smoketest/web/secure/jdbc/SampleWebSecureJdbcApplicationTests.java index ee35c052e9b2..19e2e17ebd7e 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-jdbc/src/test/java/smoketest/web/secure/jdbc/SampleWebSecureJdbcApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure-jdbc/src/test/java/smoketest/web/secure/jdbc/SampleWebSecureJdbcApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -24,7 +24,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/SampleWebSecureApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/SampleWebSecureApplicationTests.java index 6794d3e40390..d6c36befff13 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/SampleWebSecureApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-secure/src/test/java/smoketest/web/secure/SampleWebSecureApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 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. @@ -24,7 +24,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-thymeleaf/src/test/java/smoketest/web/thymeleaf/SampleWebUiApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-thymeleaf/src/test/java/smoketest/web/thymeleaf/SampleWebUiApplicationTests.java index d658586cb12b..b9509e4371b7 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-thymeleaf/src/test/java/smoketest/web/thymeleaf/SampleWebUiApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-web-thymeleaf/src/test/java/smoketest/web/thymeleaf/SampleWebUiApplicationTests.java @@ -24,7 +24,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.util.LinkedMultiValueMap; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java index d22383653c2f..d0450b917070 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -18,9 +18,9 @@ import org.junit.jupiter.api.Test; +import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.test.web.server.LocalManagementPort; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webservices/src/test/java/smoketest/webservices/SampleWsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webservices/src/test/java/smoketest/webservices/SampleWsApplicationTests.java index ae53d8cb3207..8f982e5e8251 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webservices/src/test/java/smoketest/webservices/SampleWsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webservices/src/test/java/smoketest/webservices/SampleWsApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -29,7 +29,7 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.ws.client.core.WebServiceTemplate; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/SampleWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/SampleWebSocketsApplicationTests.java index e66096c99a71..d8fb35d08fd6 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/SampleWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/SampleWebSocketsApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -33,7 +33,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/echo/CustomContainerWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/echo/CustomContainerWebSocketsApplicationTests.java index ccfb5ff35b8e..ddafe23c9a55 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/echo/CustomContainerWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-jetty/src/test/java/smoketest/websocket/jetty/echo/CustomContainerWebSocketsApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -35,8 +35,8 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/SampleWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/SampleWebSocketsApplicationTests.java index 642e60b98394..c76d16b7ef42 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/SampleWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/SampleWebSocketsApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -33,7 +33,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/echo/CustomContainerWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/echo/CustomContainerWebSocketsApplicationTests.java index 5f2611993153..bc935fb5c977 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/echo/CustomContainerWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-tomcat/src/test/java/smoketest/websocket/tomcat/echo/CustomContainerWebSocketsApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -35,8 +35,8 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/SampleWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/SampleWebSocketsApplicationTests.java index 0ab9771969b1..a2648eb93308 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/SampleWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/SampleWebSocketsApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -33,7 +33,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/echo/CustomContainerWebSocketsApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/echo/CustomContainerWebSocketsApplicationTests.java index f0a361fa0587..471b8551f23b 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/echo/CustomContainerWebSocketsApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-websocket-undertow/src/test/java/smoketest/websocket/undertow/echo/CustomContainerWebSocketsApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2019 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. @@ -35,8 +35,8 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; diff --git a/src/checkstyle/import-control.xml b/src/checkstyle/import-control.xml index 089b4371a989..397dc03fb6ae 100644 --- a/src/checkstyle/import-control.xml +++ b/src/checkstyle/import-control.xml @@ -93,9 +93,6 @@ - - - From 9fb8bfda652bffe9ce280b469bd095cebc114914 Mon Sep 17 00:00:00 2001 From: Almog Tavor Date: Wed, 20 Apr 2022 19:35:28 +0300 Subject: [PATCH 12/12] Fix: formatting and checkstyle notes --- .../autoconfigure/kafka/ReactiveKafkaProperties.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java index 6ebeaa8f28d0..29ca59942dff 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/ReactiveKafkaProperties.java @@ -22,11 +22,6 @@ import java.util.Map; import java.util.regex.Pattern; -import org.apache.kafka.clients.consumer.KafkaConsumer; -import org.apache.kafka.clients.consumer.RetriableCommitFailedException; -import org.apache.kafka.clients.producer.ProducerConfig; -import reactor.kafka.receiver.KafkaReceiver; - import org.springframework.boot.context.properties.ConfigurationProperties; /** @@ -105,8 +100,8 @@ public static class Receiver { private int atmostOnceCommitAheadSize; /** - * Configures the maximum number of consecutive non-fatal RetriableCommitFailedException - * commit failures that are tolerated. + * Configures the maximum number of consecutive non-fatal + * RetriableCommitFailedException commit failures that are tolerated. */ private int maxCommitAttempts;