From fc5339f81c82f2c79016ca4b88d787f0b09eb2a4 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Sun, 30 Apr 2023 16:47:58 -0700 Subject: [PATCH] Polish --- ...ectionDetailsFactoryNotFoundException.java | 12 ++- .../ConnectionDetailsNotFoundException.java | 12 ++- .../service/connection/BeanOrigin.java | 12 ++- ...r.java => ConnectionDetailsRegistrar.java} | 19 ++--- .../ServiceConnectionAutoConfiguration.java | 57 +------------ ...eConnectionAutoConfigurationRegistrar.java | 80 +++++++++++++++++++ .../ServiceConnectionContextCustomizer.java | 4 +- ...rviceConnectionAutoConfigurationTests.java | 3 +- 8 files changed, 118 insertions(+), 81 deletions(-) rename spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/{ContainerConnectionSourcesRegistrar.java => ConnectionDetailsRegistrar.java} (82%) create mode 100644 spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionAutoConfigurationRegistrar.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsFactoryNotFoundException.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsFactoryNotFoundException.java index 84b50fb814..3d5ace1df6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsFactoryNotFoundException.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsFactoryNotFoundException.java @@ -27,8 +27,16 @@ package org.springframework.boot.autoconfigure.service.connection; */ public class ConnectionDetailsFactoryNotFoundException extends RuntimeException { - public ConnectionDetailsFactoryNotFoundException(S source) { - super("No ConnectionDetailsFactory found for source '%s'".formatted(source)); + ConnectionDetailsFactoryNotFoundException(S source) { + this("No ConnectionDetailsFactory found for source '%s'".formatted(source)); + } + + public ConnectionDetailsFactoryNotFoundException(String message) { + super(message); + } + + public ConnectionDetailsFactoryNotFoundException(String message, Throwable cause) { + super(message, cause); } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsNotFoundException.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsNotFoundException.java index 0f63cdecfe..7715386bd8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsNotFoundException.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/service/connection/ConnectionDetailsNotFoundException.java @@ -27,8 +27,16 @@ package org.springframework.boot.autoconfigure.service.connection; */ public class ConnectionDetailsNotFoundException extends RuntimeException { - public ConnectionDetailsNotFoundException(S source) { - super("No ConnectionDetails found for source '%s'".formatted(source)); + ConnectionDetailsNotFoundException(S source) { + this("No ConnectionDetails found for source '%s'".formatted(source)); + } + + public ConnectionDetailsNotFoundException(String message) { + super(message); + } + + public ConnectionDetailsNotFoundException(String message, Throwable cause) { + super(message, cause); } } diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/BeanOrigin.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/BeanOrigin.java index f4e3b94337..701a38d1c4 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/BeanOrigin.java +++ b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/BeanOrigin.java @@ -30,11 +30,11 @@ class BeanOrigin implements Origin { private final String beanName; - private final BeanDefinition beanDefinition; + private final String resourceDescription; BeanOrigin(String beanName, BeanDefinition beanDefinition) { this.beanName = beanName; - this.beanDefinition = beanDefinition; + this.resourceDescription = (beanDefinition != null) ? beanDefinition.getResourceDescription() : null; } @Override @@ -46,8 +46,7 @@ class BeanOrigin implements Origin { return false; } BeanOrigin other = (BeanOrigin) obj; - return Objects.equals(this.beanName, other.beanName) && Objects - .equals(this.beanDefinition.getResourceDescription(), other.beanDefinition.getResourceDescription()); + return Objects.equals(this.beanName, other.beanName); } @Override @@ -57,14 +56,13 @@ class BeanOrigin implements Origin { @Override public String toString() { - String resourceDescription = this.beanDefinition.getResourceDescription(); StringBuilder result = new StringBuilder(); result.append("Bean '"); result.append(this.beanName); result.append("'"); - if (resourceDescription != null) { + if (this.resourceDescription != null) { result.append(" defined in "); - result.append(resourceDescription); + result.append(this.resourceDescription); } return result.toString(); } diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionSourcesRegistrar.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ConnectionDetailsRegistrar.java similarity index 82% rename from spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionSourcesRegistrar.java rename to spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ConnectionDetailsRegistrar.java index c8d155162a..00f500b381 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionSourcesRegistrar.java +++ b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ConnectionDetailsRegistrar.java @@ -18,6 +18,7 @@ package org.springframework.boot.testcontainers.service.connection; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -36,35 +37,31 @@ import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; /** - * Class used to register bean definitions from a list of + * Class used to register {@link ConnectionDetails} bean definitions from * {@link ContainerConnectionSource} instances. * * @author Moritz Halbritter * @author Andy Wilkinson * @author Phillip Webb */ -class ContainerConnectionSourcesRegistrar { +class ConnectionDetailsRegistrar { - private static final Log logger = LogFactory.getLog(ContainerConnectionSourcesRegistrar.class); + private static final Log logger = LogFactory.getLog(ConnectionDetailsRegistrar.class); private final ListableBeanFactory beanFactory; private final ConnectionDetailsFactories connectionDetailsFactories; - private final List> sources; - - ContainerConnectionSourcesRegistrar(ListableBeanFactory beanFactory, - ConnectionDetailsFactories connectionDetailsFactories, List> sources) { + ConnectionDetailsRegistrar(ListableBeanFactory beanFactory, ConnectionDetailsFactories connectionDetailsFactories) { this.beanFactory = beanFactory; this.connectionDetailsFactories = connectionDetailsFactories; - this.sources = sources; } - void registerBeanDefinitions(BeanDefinitionRegistry registry) { - this.sources.forEach((source) -> registerBeanDefinition(registry, source)); + void registerBeanDefinitions(BeanDefinitionRegistry registry, Collection> sources) { + sources.forEach((source) -> registerBeanDefinitions(registry, source)); } - private void registerBeanDefinition(BeanDefinitionRegistry registry, ContainerConnectionSource source) { + private void registerBeanDefinitions(BeanDefinitionRegistry registry, ContainerConnectionSource source) { this.connectionDetailsFactories.getConnectionDetails(source, true) .forEach((connectionDetailsType, connectionDetails) -> registerBeanDefinition(registry, source, connectionDetailsType, connectionDetails)); diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionAutoConfiguration.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionAutoConfiguration.java index e9ae247d27..bda5556997 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionAutoConfiguration.java +++ b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionAutoConfiguration.java @@ -16,24 +16,12 @@ package org.springframework.boot.testcontainers.service.connection; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - import org.testcontainers.containers.Container; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigureOrder; -import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactories; -import org.springframework.boot.origin.Origin; import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.Ordered; -import org.springframework.core.type.AnnotationMetadata; /** * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration @@ -45,53 +33,10 @@ import org.springframework.core.type.AnnotationMetadata; */ @AutoConfiguration @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) -@Import(ServiceConnectionAutoConfiguration.Registrar.class) +@Import(ServiceConnectionAutoConfigurationRegistrar.class) public class ServiceConnectionAutoConfiguration { ServiceConnectionAutoConfiguration() { } - static class Registrar implements ImportBeanDefinitionRegistrar { - - private final BeanFactory beanFactory; - - Registrar(BeanFactory beanFactory) { - this.beanFactory = beanFactory; - } - - @Override - public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, - BeanDefinitionRegistry registry) { - if (this.beanFactory instanceof ConfigurableListableBeanFactory listableBeanFactory) { - ConnectionDetailsFactories connectionDetailsFactories = new ConnectionDetailsFactories(); - List> sources = getSources(listableBeanFactory); - new ContainerConnectionSourcesRegistrar(listableBeanFactory, connectionDetailsFactories, sources) - .registerBeanDefinitions(registry); - } - } - - private List> getSources(ConfigurableListableBeanFactory beanFactory) { - List> sources = new ArrayList<>(); - for (String candidate : beanFactory.getBeanNamesForType(Container.class)) { - Set annotations = beanFactory.findAllAnnotationsOnBean(candidate, - ServiceConnection.class, false); - if (!annotations.isEmpty()) { - addSources(sources, beanFactory, candidate, annotations); - } - } - return sources; - } - - private void addSources(List> sources, ConfigurableListableBeanFactory beanFactory, - String beanName, Set annotations) { - BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); - Origin origin = new BeanOrigin(beanName, beanDefinition); - Container container = beanFactory.getBean(beanName, Container.class); - for (ServiceConnection annotation : annotations) { - sources.add(new ContainerConnectionSource<>(beanName, origin, container, annotation)); - } - } - - } - } diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionAutoConfigurationRegistrar.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionAutoConfigurationRegistrar.java new file mode 100644 index 0000000000..ca5c7d0386 --- /dev/null +++ b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionAutoConfigurationRegistrar.java @@ -0,0 +1,80 @@ +/* + * Copyright 2012-2023 the original author 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.testcontainers.service.connection; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.testcontainers.containers.Container; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactories; +import org.springframework.boot.origin.Origin; +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; +import org.springframework.core.type.AnnotationMetadata; + +/** + * {@link ImportBeanDefinitionRegistrar} used by + * {@link ServiceConnectionAutoConfiguration}. + * + * @author Phillip Webb + */ +class ServiceConnectionAutoConfigurationRegistrar implements ImportBeanDefinitionRegistrar { + + private final BeanFactory beanFactory; + + ServiceConnectionAutoConfigurationRegistrar(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @Override + public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { + if (this.beanFactory instanceof ConfigurableListableBeanFactory listableBeanFactory) { + ConnectionDetailsFactories connectionDetailsFactories = new ConnectionDetailsFactories(); + List> sources = getSources(listableBeanFactory); + new ConnectionDetailsRegistrar(listableBeanFactory, connectionDetailsFactories) + .registerBeanDefinitions(registry, sources); + } + } + + private List> getSources(ConfigurableListableBeanFactory beanFactory) { + List> sources = new ArrayList<>(); + for (String candidate : beanFactory.getBeanNamesForType(Container.class)) { + Set annotations = beanFactory.findAllAnnotationsOnBean(candidate, + ServiceConnection.class, false); + if (!annotations.isEmpty()) { + addSources(sources, beanFactory, candidate, annotations); + } + } + return sources; + } + + private void addSources(List> sources, ConfigurableListableBeanFactory beanFactory, + String beanName, Set annotations) { + BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); + Origin origin = new BeanOrigin(beanName, beanDefinition); + Container container = beanFactory.getBean(beanName, Container.class); + for (ServiceConnection annotation : annotations) { + sources.add(new ContainerConnectionSource<>(beanName, origin, container, annotation)); + } + } + +} diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionContextCustomizer.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionContextCustomizer.java index 2d50bef7d9..8f8e72d2a3 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionContextCustomizer.java +++ b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionContextCustomizer.java @@ -53,8 +53,8 @@ class ServiceConnectionContextCustomizer implements ContextCustomizer { public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) { ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); if (beanFactory instanceof BeanDefinitionRegistry registry) { - new ContainerConnectionSourcesRegistrar(beanFactory, this.connectionDetailsFactories, this.sources) - .registerBeanDefinitions(registry); + new ConnectionDetailsRegistrar(beanFactory, this.connectionDetailsFactories) + .registerBeanDefinitions(registry, this.sources); } } diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionAutoConfigurationTests.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionAutoConfigurationTests.java index 84388f6096..27ba5303d3 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionAutoConfigurationTests.java @@ -33,7 +33,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; /** - * Tests for {@link ServiceConnectionAutoConfiguration}. + * Tests for {@link ServiceConnectionAutoConfiguration} and + * {@link ServiceConnectionAutoConfigurationRegistrar}. * * @author Phillip Webb */