Create service connections from Testcontainers-managed containers
Building upon the auto-configuration support for service connections, this commit adds support for deriving connection details from a Testcontainers-managed container. Several service-specific annotations have been introduced. These annotations can be used on a container field to indicate that it is a source of the details for a service connection. See gh-34658 Co-Authored-By: Phillip Webb <pwebb@vmware.com> Co-Authored-By: Mortitz Halbritter <mkammerer@vmware.com>pull/34759/head
parent
8ec266bea4
commit
95f45eab1f
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.docs.howto.testing.testcontainers.serviceconnections;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.testcontainers.containers.Neo4jContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import org.springframework.boot.test.autoconfigure.neo4j.Neo4jServiceConnection;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
@Testcontainers
|
||||
class MyIntegrationTests {
|
||||
|
||||
@Container
|
||||
@Neo4jServiceConnection
|
||||
static Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.2");
|
||||
|
||||
@Test
|
||||
void myTest() {
|
||||
// ...
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.docs.howto.testing.testcontainers.serviceconnection
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.boot.test.autoconfigure.neo4j.Neo4jServiceConnection;
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.test.context.DynamicPropertyRegistry
|
||||
import org.springframework.test.context.DynamicPropertySource
|
||||
import org.testcontainers.containers.Neo4jContainer
|
||||
import org.testcontainers.junit.jupiter.Container
|
||||
import org.testcontainers.junit.jupiter.Testcontainers
|
||||
|
||||
@SpringBootTest
|
||||
@Testcontainers
|
||||
internal class MyIntegrationTests {
|
||||
|
||||
@Test
|
||||
fun myTest() {
|
||||
// ...
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@Container
|
||||
@Neo4jServiceConnection
|
||||
var neo4j: Neo4jContainer<*> = Neo4jContainer<Nothing>("neo4j:4.2")
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.amqp;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
import org.testcontainers.containers.RabbitMQContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.amqp.RabbitConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionSource;
|
||||
|
||||
/**
|
||||
* {@link ContainerConnectionDetailsFactory} for
|
||||
* {@link RabbitServiceConnection @RabbitServiceConnection}-annotated
|
||||
* {@link RabbitMQContainer} fields.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class RabbitContainerConnectionDetailsFactory
|
||||
extends ContainerConnectionDetailsFactory<RabbitServiceConnection, RabbitConnectionDetails, RabbitMQContainer> {
|
||||
|
||||
@Override
|
||||
protected RabbitConnectionDetails getContainerConnectionDetails(
|
||||
ContainerConnectionSource<RabbitServiceConnection, RabbitConnectionDetails, RabbitMQContainer> source) {
|
||||
return new RabbitMqContainerConnectionDetails(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link RabbitConnectionDetails} backed by a {@link ContainerConnectionSource}.
|
||||
*/
|
||||
private static final class RabbitMqContainerConnectionDetails extends ContainerConnectionDetails
|
||||
implements RabbitConnectionDetails {
|
||||
|
||||
private final RabbitMQContainer container;
|
||||
|
||||
private RabbitMqContainerConnectionDetails(
|
||||
ContainerConnectionSource<RabbitServiceConnection, RabbitConnectionDetails, RabbitMQContainer> source) {
|
||||
super(source);
|
||||
this.container = source.getContainer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return this.container.getAdminUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return this.container.getAdminPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVirtualHost() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Address> getAddresses() {
|
||||
URI uri = URI.create(this.container.getAmqpUrl());
|
||||
return List.of(new Address(uri.getHost(), uri.getPort()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.amqp;
|
||||
|
||||
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.boot.autoconfigure.amqp.RabbitConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ServiceConnection;
|
||||
|
||||
/**
|
||||
* Annotation that indicates that a field provides a RabbitMQ service connection.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
* @since 3.1.0
|
||||
* @see RabbitConnectionDetails
|
||||
* @see ServiceConnection
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD, ElementType.TYPE })
|
||||
@ServiceConnection(RabbitConnectionDetails.class)
|
||||
public @interface RabbitServiceConnection {
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for using RabbitMQ in tests.
|
||||
*/
|
||||
package org.springframework.boot.test.autoconfigure.amqp;
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.cassandra;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.testcontainers.containers.CassandraContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.cassandra.CassandraConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionSource;
|
||||
|
||||
/**
|
||||
* {@link ContainerConnectionDetailsFactory} for
|
||||
* {@link CassandraServiceConnection @CassandraServiceConnection}-annotated
|
||||
* {@link CassandraContainer} fields.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class CassandraContainerConnectionDetailsFactory extends
|
||||
ContainerConnectionDetailsFactory<CassandraServiceConnection, CassandraConnectionDetails, CassandraContainer<?>> {
|
||||
|
||||
@Override
|
||||
protected CassandraConnectionDetails getContainerConnectionDetails(
|
||||
ContainerConnectionSource<CassandraServiceConnection, CassandraConnectionDetails, CassandraContainer<?>> source) {
|
||||
return new CassandraContainerConnectionDetails(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link CassandraConnectionDetails} backed by a {@link ContainerConnectionSource}.
|
||||
*/
|
||||
private static final class CassandraContainerConnectionDetails extends ContainerConnectionDetails
|
||||
implements CassandraConnectionDetails {
|
||||
|
||||
private final CassandraContainer<?> container;
|
||||
|
||||
private CassandraContainerConnectionDetails(
|
||||
ContainerConnectionSource<CassandraServiceConnection, CassandraConnectionDetails, CassandraContainer<?>> source) {
|
||||
super(source);
|
||||
this.container = source.getContainer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Node> getContactPoints() {
|
||||
return List.of(new Node(this.container.getContactPoint().getHostString(),
|
||||
this.container.getContactPoint().getPort()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return this.container.getUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return this.container.getPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocalDatacenter() {
|
||||
return this.container.getLocalDatacenter();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.cassandra;
|
||||
|
||||
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.boot.autoconfigure.cassandra.CassandraConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ServiceConnection;
|
||||
|
||||
/**
|
||||
* Annotation that indicates that a field provides a Cassandra service connection.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
* @since 3.1.0
|
||||
* @see CassandraConnectionDetails
|
||||
* @see ServiceConnection
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD, ElementType.TYPE })
|
||||
@ServiceConnection(CassandraConnectionDetails.class)
|
||||
public @interface CassandraServiceConnection {
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for using Cassandra in tests.
|
||||
*/
|
||||
package org.springframework.boot.test.autoconfigure.cassandra;
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.couchbase;
|
||||
|
||||
import org.testcontainers.couchbase.CouchbaseContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.couchbase.CouchbaseConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionSource;
|
||||
|
||||
/**
|
||||
* {@link ContainerConnectionDetailsFactory} for
|
||||
* {@link CouchbaseServiceConnection @CouchbaseServiceConnection}-annotated
|
||||
* {@link CouchbaseContainer} fields.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class CouchbaseContainerConnectionDetailsFactory extends
|
||||
ContainerConnectionDetailsFactory<CouchbaseServiceConnection, CouchbaseConnectionDetails, CouchbaseContainer> {
|
||||
|
||||
@Override
|
||||
protected CouchbaseConnectionDetails getContainerConnectionDetails(
|
||||
ContainerConnectionSource<CouchbaseServiceConnection, CouchbaseConnectionDetails, CouchbaseContainer> source) {
|
||||
return new CouchbaseContainerConnectionDetails(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link CouchbaseConnectionDetails} backed by a {@link ContainerConnectionSource}.
|
||||
*/
|
||||
private static final class CouchbaseContainerConnectionDetails extends ContainerConnectionDetails
|
||||
implements CouchbaseConnectionDetails {
|
||||
|
||||
private final CouchbaseContainer container;
|
||||
|
||||
private CouchbaseContainerConnectionDetails(
|
||||
ContainerConnectionSource<CouchbaseServiceConnection, CouchbaseConnectionDetails, CouchbaseContainer> source) {
|
||||
super(source);
|
||||
this.container = source.getContainer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return this.container.getUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return this.container.getPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConnectionString() {
|
||||
return this.container.getConnectionString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.couchbase;
|
||||
|
||||
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.boot.autoconfigure.couchbase.CouchbaseConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ServiceConnection;
|
||||
|
||||
/**
|
||||
* Annotation that indicates that a field provides a Couchbase service connection.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
* @since 3.1.0
|
||||
* @see CouchbaseConnectionDetails
|
||||
* @see ServiceConnection
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD, ElementType.TYPE })
|
||||
@ServiceConnection(CouchbaseConnectionDetails.class)
|
||||
public @interface CouchbaseServiceConnection {
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for using Couchbase in tests.
|
||||
*/
|
||||
package org.springframework.boot.test.autoconfigure.couchbase;
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.data.redis;
|
||||
|
||||
import org.testcontainers.containers.GenericContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionSource;
|
||||
|
||||
/**
|
||||
* {@link ContainerConnectionDetailsFactory} for
|
||||
* {@link RedisServiceConnection @RedisServiceConnection}-annotated
|
||||
* {@link GenericContainer} fields.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class RedisContainerConnectionDetailsFactory
|
||||
extends ContainerConnectionDetailsFactory<RedisServiceConnection, RedisConnectionDetails, GenericContainer<?>> {
|
||||
|
||||
@Override
|
||||
public RedisConnectionDetails getContainerConnectionDetails(
|
||||
ContainerConnectionSource<RedisServiceConnection, RedisConnectionDetails, GenericContainer<?>> source) {
|
||||
return new RedisContainerConnectionDetails(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link RedisConnectionDetails} backed by a {@link ContainerConnectionSource}.
|
||||
*/
|
||||
private static final class RedisContainerConnectionDetails extends ContainerConnectionDetails
|
||||
implements RedisConnectionDetails {
|
||||
|
||||
private final Standalone standalone;
|
||||
|
||||
private RedisContainerConnectionDetails(
|
||||
ContainerConnectionSource<RedisServiceConnection, RedisConnectionDetails, GenericContainer<?>> source) {
|
||||
super(source);
|
||||
this.standalone = new Standalone() {
|
||||
|
||||
@Override
|
||||
public String getHost() {
|
||||
return source.getContainer().getHost();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
return source.getContainer().getFirstMappedPort();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Standalone getStandalone() {
|
||||
return this.standalone;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.data.redis;
|
||||
|
||||
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.boot.autoconfigure.data.redis.RedisConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ServiceConnection;
|
||||
|
||||
/**
|
||||
* Annotation that indicates that a field provides a Redis service connection.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @since 3.1.0
|
||||
* @see RedisConnectionDetails
|
||||
* @see ServiceConnection
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD, ElementType.TYPE })
|
||||
@ServiceConnection(RedisConnectionDetails.class)
|
||||
public @interface RedisServiceConnection {
|
||||
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.elasticsearch;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.testcontainers.containers.GenericContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails;
|
||||
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails.Node.Protocol;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionSource;
|
||||
|
||||
/**
|
||||
* {@link ContainerConnectionDetailsFactory} for
|
||||
* {@link ElasticsearchServiceConnection @ElasticsearchServiceConnection}-annotated
|
||||
* {@link GenericContainer} fields.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ElasticsearchContainerConnectionDetailsFactory extends
|
||||
ContainerConnectionDetailsFactory<ElasticsearchServiceConnection, ElasticsearchConnectionDetails, GenericContainer<?>> {
|
||||
|
||||
private static final int DEFAULT_PORT = 9200;
|
||||
|
||||
@Override
|
||||
protected ElasticsearchConnectionDetails getContainerConnectionDetails(
|
||||
ContainerConnectionSource<ElasticsearchServiceConnection, ElasticsearchConnectionDetails, GenericContainer<?>> source) {
|
||||
return new ElasticsearchContainerConnectionDetails(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ElasticsearchConnectionDetails} backed by a
|
||||
* {@link ContainerConnectionSource}.
|
||||
*/
|
||||
private static final class ElasticsearchContainerConnectionDetails extends ContainerConnectionDetails
|
||||
implements ElasticsearchConnectionDetails {
|
||||
|
||||
private final List<Node> nodes;
|
||||
|
||||
private ElasticsearchContainerConnectionDetails(
|
||||
ContainerConnectionSource<ElasticsearchServiceConnection, ElasticsearchConnectionDetails, GenericContainer<?>> source) {
|
||||
super(source);
|
||||
this.nodes = List.of(new Node(source.getContainer().getHost(),
|
||||
source.getContainer().getMappedPort(DEFAULT_PORT), Protocol.HTTP, null, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Node> getNodes() {
|
||||
return this.nodes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.elasticsearch;
|
||||
|
||||
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.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ServiceConnection;
|
||||
|
||||
/**
|
||||
* Annotation that indicates that a field provides a Elasticsearch service connection.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
* @since 3.1.0
|
||||
* @see ElasticsearchConnectionDetails
|
||||
* @see ServiceConnection
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD, ElementType.TYPE })
|
||||
@ServiceConnection(ElasticsearchConnectionDetails.class)
|
||||
public @interface ElasticsearchServiceConnection {
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for using Elasticsearch in tests.
|
||||
*/
|
||||
package org.springframework.boot.test.autoconfigure.elasticsearch;
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.influx;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.testcontainers.containers.InfluxDBContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.influx.InfluxDbConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionSource;
|
||||
|
||||
/**
|
||||
* {@link ContainerConnectionDetailsFactory} for
|
||||
* {@link InfluxDbServiceConnection @InfluxDbServiceConnection}-annotated
|
||||
* {@link InfluxDBContainer} fields.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class InfluxDbContainerConnectionDetailsFactory extends
|
||||
ContainerConnectionDetailsFactory<InfluxDbServiceConnection, InfluxDbConnectionDetails, InfluxDBContainer<?>> {
|
||||
|
||||
@Override
|
||||
protected InfluxDbConnectionDetails getContainerConnectionDetails(
|
||||
ContainerConnectionSource<InfluxDbServiceConnection, InfluxDbConnectionDetails, InfluxDBContainer<?>> source) {
|
||||
return new InfluxDbContainerConnectionDetails(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link InfluxDbConnectionDetails} backed by a {@link ContainerConnectionSource}.
|
||||
*/
|
||||
private static final class InfluxDbContainerConnectionDetails extends ContainerConnectionDetails
|
||||
implements InfluxDbConnectionDetails {
|
||||
|
||||
private final InfluxDBContainer<?> container;
|
||||
|
||||
private InfluxDbContainerConnectionDetails(
|
||||
ContainerConnectionSource<InfluxDbServiceConnection, InfluxDbConnectionDetails, InfluxDBContainer<?>> source) {
|
||||
super(source);
|
||||
this.container = source.getContainer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return this.container.getUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return this.container.getPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getUrl() {
|
||||
return URI.create(this.container.getUrl());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.influx;
|
||||
|
||||
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.boot.autoconfigure.influx.InfluxDbConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ServiceConnection;
|
||||
|
||||
/**
|
||||
* Annotation that indicates that a field provides an InfluxDB service connection.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
* @since 3.1.0
|
||||
* @see InfluxDbConnectionDetails
|
||||
* @see ServiceConnection
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD, ElementType.TYPE })
|
||||
@ServiceConnection(InfluxDbConnectionDetails.class)
|
||||
public @interface InfluxDbServiceConnection {
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for using InfluxDB in tests.
|
||||
*/
|
||||
package org.springframework.boot.test.autoconfigure.influx;
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.jdbc;
|
||||
|
||||
import org.testcontainers.containers.JdbcDatabaseContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionSource;
|
||||
|
||||
/**
|
||||
* {@link ContainerConnectionDetailsFactory} for
|
||||
* {@link JdbcServiceConnection @JdbcServiceConnection}-annotated
|
||||
* {@link JdbcDatabaseContainer} fields.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class JdbcContainerConnectionDetailsFactory extends
|
||||
ContainerConnectionDetailsFactory<JdbcServiceConnection, JdbcConnectionDetails, JdbcDatabaseContainer<?>> {
|
||||
|
||||
@Override
|
||||
protected JdbcConnectionDetails getContainerConnectionDetails(
|
||||
ContainerConnectionSource<JdbcServiceConnection, JdbcConnectionDetails, JdbcDatabaseContainer<?>> source) {
|
||||
return new JdbcContainerConnectionDetails(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link JdbcConnectionDetails} backed by a {@link ContainerConnectionSource}.
|
||||
*/
|
||||
private static final class JdbcContainerConnectionDetails extends ContainerConnectionDetails
|
||||
implements JdbcConnectionDetails {
|
||||
|
||||
private final JdbcDatabaseContainer<?> container;
|
||||
|
||||
private JdbcContainerConnectionDetails(
|
||||
ContainerConnectionSource<JdbcServiceConnection, JdbcConnectionDetails, JdbcDatabaseContainer<?>> source) {
|
||||
super(source);
|
||||
this.container = source.getContainer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return this.container.getUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return this.container.getPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJdbcUrl() {
|
||||
return this.container.getJdbcUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDriverClassName() {
|
||||
return this.container.getDriverClassName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.jdbc;
|
||||
|
||||
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.boot.autoconfigure.jdbc.JdbcConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ServiceConnection;
|
||||
|
||||
/**
|
||||
* Annotation that indicates that a field provides a JDBC database service connection.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @since 3.1.0
|
||||
* @see JdbcConnectionDetails
|
||||
* @see ServiceConnection
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD, ElementType.TYPE })
|
||||
@ServiceConnection(JdbcConnectionDetails.class)
|
||||
public @interface JdbcServiceConnection {
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.kafka;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
import org.testcontainers.containers.KafkaContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.kafka.KafkaConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionSource;
|
||||
|
||||
/**
|
||||
* {@link ContainerConnectionDetailsFactory} for
|
||||
* {@link KafkaServiceConnection @KafkaServiceConnection}-annotated {@link KafkaContainer}
|
||||
* fields.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class KafkaContainerConnectionDetailsFactory
|
||||
extends ContainerConnectionDetailsFactory<KafkaServiceConnection, KafkaConnectionDetails, KafkaContainer> {
|
||||
|
||||
@Override
|
||||
protected KafkaConnectionDetails getContainerConnectionDetails(
|
||||
ContainerConnectionSource<KafkaServiceConnection, KafkaConnectionDetails, KafkaContainer> source) {
|
||||
return new KafkaContainerConnectionDetails(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link KafkaConnectionDetails} backed by a {@link ContainerConnectionSource}.
|
||||
*/
|
||||
private static final class KafkaContainerConnectionDetails extends ContainerConnectionDetails
|
||||
implements KafkaConnectionDetails {
|
||||
|
||||
private final KafkaContainer container;
|
||||
|
||||
private KafkaContainerConnectionDetails(
|
||||
ContainerConnectionSource<KafkaServiceConnection, KafkaConnectionDetails, KafkaContainer> source) {
|
||||
super(source);
|
||||
this.container = source.getContainer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Node> getBootstrapNodes() {
|
||||
URI uri = URI.create(this.container.getBootstrapServers());
|
||||
return List.of(new Node(uri.getHost(), uri.getPort()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.kafka;
|
||||
|
||||
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.boot.autoconfigure.kafka.KafkaConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ServiceConnection;
|
||||
|
||||
/**
|
||||
* Annotation that indicates that a field provides a Kafka service connection.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @since 3.1.0
|
||||
* @see KafkaConnectionDetails
|
||||
* @see ServiceConnection
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD, ElementType.TYPE })
|
||||
@ServiceConnection(KafkaConnectionDetails.class)
|
||||
public @interface KafkaServiceConnection {
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for using Kafka in tests.
|
||||
*/
|
||||
package org.springframework.boot.test.autoconfigure.kafka;
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.mongo;
|
||||
|
||||
import com.mongodb.ConnectionString;
|
||||
import org.testcontainers.containers.MongoDBContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionSource;
|
||||
|
||||
/**
|
||||
* {@link ContainerConnectionDetailsFactory} for
|
||||
* {@link MongoServiceConnection @MongoServiceConnection}-annotated
|
||||
* {@link MongoDBContainer} fields.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MongoContainerConnectionDetailsFactory
|
||||
extends ContainerConnectionDetailsFactory<MongoServiceConnection, MongoConnectionDetails, MongoDBContainer> {
|
||||
|
||||
@Override
|
||||
protected MongoConnectionDetails getContainerConnectionDetails(
|
||||
ContainerConnectionSource<MongoServiceConnection, MongoConnectionDetails, MongoDBContainer> source) {
|
||||
return new MongoContainerConnectionDetails(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link MongoConnectionDetails} backed by a {@link ContainerConnectionSource}.
|
||||
*/
|
||||
private static final class MongoContainerConnectionDetails extends ContainerConnectionDetails
|
||||
implements MongoConnectionDetails {
|
||||
|
||||
private final ConnectionString connectionString;
|
||||
|
||||
private MongoContainerConnectionDetails(
|
||||
ContainerConnectionSource<MongoServiceConnection, MongoConnectionDetails, MongoDBContainer> source) {
|
||||
super(source);
|
||||
this.connectionString = new ConnectionString(source.getContainer().getReplicaSetUrl());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionString getConnectionString() {
|
||||
return this.connectionString;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.mongo;
|
||||
|
||||
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.boot.autoconfigure.mongo.MongoConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ServiceConnection;
|
||||
|
||||
/**
|
||||
* Annotation that indicates that a field provides a Mongo service connection.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @since 3.1.0
|
||||
* @see MongoConnectionDetails
|
||||
* @see ServiceConnection
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD, ElementType.TYPE })
|
||||
@ServiceConnection(MongoConnectionDetails.class)
|
||||
public @interface MongoServiceConnection {
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for using Mongo in tests.
|
||||
*/
|
||||
package org.springframework.boot.test.autoconfigure.mongo;
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.neo4j;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.neo4j.driver.AuthToken;
|
||||
import org.neo4j.driver.AuthTokens;
|
||||
import org.testcontainers.containers.Neo4jContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.neo4j.Neo4jConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionSource;
|
||||
|
||||
/**
|
||||
* {@link ContainerConnectionDetailsFactory} for
|
||||
* {@link Neo4jServiceConnection @Neo4jServiceConnection}-annotated {@link Neo4jContainer}
|
||||
* fields.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class Neo4jContainerConnectionDetailsFactory
|
||||
extends ContainerConnectionDetailsFactory<Neo4jServiceConnection, Neo4jConnectionDetails, Neo4jContainer<?>> {
|
||||
|
||||
@Override
|
||||
protected Neo4jConnectionDetails getContainerConnectionDetails(
|
||||
ContainerConnectionSource<Neo4jServiceConnection, Neo4jConnectionDetails, Neo4jContainer<?>> source) {
|
||||
return new Neo4jContainerConnectionDetails(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Neo4jConnectionDetails} backed by a {@link ContainerConnectionSource}.
|
||||
*/
|
||||
private static final class Neo4jContainerConnectionDetails extends ContainerConnectionDetails
|
||||
implements Neo4jConnectionDetails {
|
||||
|
||||
private final Neo4jContainer<?> container;
|
||||
|
||||
private Neo4jContainerConnectionDetails(
|
||||
ContainerConnectionSource<Neo4jServiceConnection, Neo4jConnectionDetails, Neo4jContainer<?>> source) {
|
||||
super(source);
|
||||
this.container = source.getContainer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getUri() {
|
||||
return URI.create(this.container.getBoltUrl());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthToken getAuthToken() {
|
||||
String password = this.container.getAdminPassword();
|
||||
return (password != null) ? AuthTokens.basic("neo4j", password) : AuthTokens.none();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.neo4j;
|
||||
|
||||
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.boot.autoconfigure.neo4j.Neo4jConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ServiceConnection;
|
||||
|
||||
/**
|
||||
* Annotation that indicates a field provides a Neo4j service connection.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @since 3.1.0
|
||||
* @see Neo4jConnectionDetails
|
||||
* @see ServiceConnection
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD, ElementType.TYPE })
|
||||
@ServiceConnection(Neo4jConnectionDetails.class)
|
||||
public @interface Neo4jServiceConnection {
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for using Neo4j in tests.
|
||||
*/
|
||||
package org.springframework.boot.test.autoconfigure.neo4j;
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.r2dbc;
|
||||
|
||||
import io.r2dbc.spi.ConnectionFactoryOptions;
|
||||
import org.testcontainers.containers.MariaDBContainer;
|
||||
import org.testcontainers.containers.MariaDBR2DBCDatabaseContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
|
||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionSource;
|
||||
|
||||
/**
|
||||
* {@link ConnectionDetailsFactory} for
|
||||
* {@link R2dbcServiceConnection @R2dbcServiceConnection}- annotated
|
||||
* {@link MariaDBContainer} fields.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MariaDbR2dbcContainerConnectionDetailsFactory
|
||||
extends ContainerConnectionDetailsFactory<R2dbcServiceConnection, R2dbcConnectionDetails, MariaDBContainer<?>> {
|
||||
|
||||
@Override
|
||||
public R2dbcConnectionDetails getContainerConnectionDetails(
|
||||
ContainerConnectionSource<R2dbcServiceConnection, R2dbcConnectionDetails, MariaDBContainer<?>> source) {
|
||||
return new R2dbcDatabaseContainerConnectionDetails(source.getContainer());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link R2dbcConnectionDetails} backed by a {@link ContainerConnectionSource}.
|
||||
*/
|
||||
private static final class R2dbcDatabaseContainerConnectionDetails implements R2dbcConnectionDetails {
|
||||
|
||||
private final MariaDBContainer<?> container;
|
||||
|
||||
private R2dbcDatabaseContainerConnectionDetails(MariaDBContainer<?> container) {
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionFactoryOptions getConnectionFactoryOptions() {
|
||||
return MariaDBR2DBCDatabaseContainer.getOptions(this.container);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.r2dbc;
|
||||
|
||||
import io.r2dbc.spi.ConnectionFactoryOptions;
|
||||
import org.testcontainers.containers.MySQLContainer;
|
||||
import org.testcontainers.containers.MySQLR2DBCDatabaseContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
|
||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionSource;
|
||||
|
||||
/**
|
||||
* {@link ConnectionDetailsFactory} for
|
||||
* {@link R2dbcServiceConnection @R2dbcServiceConnection}- annotated
|
||||
* {@link MySQLContainer} fields.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MySqlR2dbcContainerConnectionDetailsFactory
|
||||
extends ContainerConnectionDetailsFactory<R2dbcServiceConnection, R2dbcConnectionDetails, MySQLContainer<?>> {
|
||||
|
||||
@Override
|
||||
public R2dbcConnectionDetails getContainerConnectionDetails(
|
||||
ContainerConnectionSource<R2dbcServiceConnection, R2dbcConnectionDetails, MySQLContainer<?>> source) {
|
||||
return new R2dbcDatabaseContainerConnectionDetails(source.getContainer());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link R2dbcConnectionDetails} backed by a {@link ContainerConnectionSource}.
|
||||
*/
|
||||
private static final class R2dbcDatabaseContainerConnectionDetails implements R2dbcConnectionDetails {
|
||||
|
||||
private final MySQLContainer<?> container;
|
||||
|
||||
private R2dbcDatabaseContainerConnectionDetails(MySQLContainer<?> container) {
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionFactoryOptions getConnectionFactoryOptions() {
|
||||
return MySQLR2DBCDatabaseContainer.getOptions(this.container);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.r2dbc;
|
||||
|
||||
import io.r2dbc.spi.ConnectionFactoryOptions;
|
||||
import org.testcontainers.containers.PostgreSQLContainer;
|
||||
import org.testcontainers.containers.PostgreSQLR2DBCDatabaseContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
|
||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionSource;
|
||||
|
||||
/**
|
||||
* {@link ConnectionDetailsFactory} for {@link R2dbcServiceConnection @R2dbcConnection}
|
||||
* annotated {@link PostgreSQLContainer} fields.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class PostgresR2dbcContainerConnectionDetailsFactory extends
|
||||
ContainerConnectionDetailsFactory<R2dbcServiceConnection, R2dbcConnectionDetails, PostgreSQLContainer<?>> {
|
||||
|
||||
@Override
|
||||
public R2dbcConnectionDetails getContainerConnectionDetails(
|
||||
ContainerConnectionSource<R2dbcServiceConnection, R2dbcConnectionDetails, PostgreSQLContainer<?>> source) {
|
||||
return new R2dbcDatabaseContainerConnectionDetails(source.getContainer());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link R2dbcConnectionDetails} backed by a {@link ContainerConnectionSource}.
|
||||
*/
|
||||
private static final class R2dbcDatabaseContainerConnectionDetails implements R2dbcConnectionDetails {
|
||||
|
||||
private final PostgreSQLContainer<?> container;
|
||||
|
||||
private R2dbcDatabaseContainerConnectionDetails(PostgreSQLContainer<?> container) {
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionFactoryOptions getConnectionFactoryOptions() {
|
||||
return PostgreSQLR2DBCDatabaseContainer.getOptions(this.container);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.r2dbc;
|
||||
|
||||
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.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ServiceConnection;
|
||||
|
||||
/**
|
||||
* Annotation that indicates a field provides a R2DBC database service connection.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @since 3.1.0
|
||||
* @see ServiceConnection
|
||||
* @see R2dbcConnectionDetails
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD, ElementType.TYPE })
|
||||
@ServiceConnection(R2dbcConnectionDetails.class)
|
||||
public @interface R2dbcServiceConnection {
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.r2dbc;
|
||||
|
||||
import io.r2dbc.spi.ConnectionFactoryOptions;
|
||||
import org.testcontainers.containers.MSSQLR2DBCDatabaseContainer;
|
||||
import org.testcontainers.containers.MSSQLServerContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
|
||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionDetailsFactory;
|
||||
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionSource;
|
||||
|
||||
/**
|
||||
* {@link ConnectionDetailsFactory} for
|
||||
* {@link R2dbcServiceConnection @R2dbcServiceConnection}- annotated
|
||||
* {@link MSSQLServerContainer} fields.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class SqlServerR2dbcContainerConnectionDetailsFactory extends
|
||||
ContainerConnectionDetailsFactory<R2dbcServiceConnection, R2dbcConnectionDetails, MSSQLServerContainer<?>> {
|
||||
|
||||
@Override
|
||||
public R2dbcConnectionDetails getContainerConnectionDetails(
|
||||
ContainerConnectionSource<R2dbcServiceConnection, R2dbcConnectionDetails, MSSQLServerContainer<?>> source) {
|
||||
return new R2dbcDatabaseContainerConnectionDetails(source.getContainer());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link R2dbcConnectionDetails} backed by a {@link ContainerConnectionSource}.
|
||||
*/
|
||||
private static final class R2dbcDatabaseContainerConnectionDetails implements R2dbcConnectionDetails {
|
||||
|
||||
private final MSSQLServerContainer<?> container;
|
||||
|
||||
private R2dbcDatabaseContainerConnectionDetails(MSSQLServerContainer<?> container) {
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionFactoryOptions getConnectionFactoryOptions() {
|
||||
return MSSQLR2DBCDatabaseContainer.getOptions(this.container);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for using R2DBC in tests.
|
||||
*/
|
||||
package org.springframework.boot.test.autoconfigure.r2dbc;
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.service.connection;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.boot.origin.Origin;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link Origin} backed by a {@link Field} and an {@link Annotation}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class AnnotatedFieldOrigin implements Origin {
|
||||
|
||||
private final Field field;
|
||||
|
||||
private final Annotation annotation;
|
||||
|
||||
AnnotatedFieldOrigin(Field field, Annotation annotation) {
|
||||
Assert.notNull(field, "Field must not be null");
|
||||
Assert.notNull(annotation, "Annotation must not be null");
|
||||
this.field = field;
|
||||
this.annotation = annotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
AnnotatedFieldOrigin other = (AnnotatedFieldOrigin) obj;
|
||||
return this.field.equals(other.field) && this.annotation.equals(other.annotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.field, this.annotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.annotation + " " + this.field;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.service.connection;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.testcontainers.containers.GenericContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
|
||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory;
|
||||
import org.springframework.boot.origin.Origin;
|
||||
import org.springframework.boot.origin.OriginProvider;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Base class for {@link ConnectionDetailsFactory} implementations that provide
|
||||
* {@link ConnectionDetails} from a {@link ContainerConnectionSource}.
|
||||
*
|
||||
* @param <A> the source annotation type. The annotation will be mergable to a
|
||||
* {@link ServiceConnection @ServiceConnection}.
|
||||
* @param <D> the connection details type
|
||||
* @param <C> the generic container type
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public abstract class ContainerConnectionDetailsFactory<A extends Annotation, D extends ConnectionDetails, C extends GenericContainer<?>>
|
||||
implements ConnectionDetailsFactory<ContainerConnectionSource<A, D, C>, D> {
|
||||
|
||||
@Override
|
||||
public final D getConnectionDetails(ContainerConnectionSource<A, D, C> source) {
|
||||
Class<?>[] generics = resolveGenerics();
|
||||
Class<?> annotationType = generics[0];
|
||||
Class<?> connectionDetailsType = generics[1];
|
||||
Class<?> containerType = generics[2];
|
||||
return (!source.accepts(annotationType, connectionDetailsType, containerType)) ? null
|
||||
: getContainerConnectionDetails(source);
|
||||
}
|
||||
|
||||
private Class<?>[] resolveGenerics() {
|
||||
return ResolvableType.forClass(ContainerConnectionDetailsFactory.class, getClass()).resolveGenerics();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link ConnectionDetails} from the given {@link ContainerConnectionSource}
|
||||
* {@code source}. May return {@code null} if no connection can be created. Result
|
||||
* types should consider extending {@link ContainerConnectionDetails}.
|
||||
* @param source the source
|
||||
* @return the service connection or {@code null}.
|
||||
*/
|
||||
protected abstract D getContainerConnectionDetails(ContainerConnectionSource<A, D, C> source);
|
||||
|
||||
/**
|
||||
* Convenient base class for {@link ConnectionDetails} results that are backed by a
|
||||
* {@link ContainerConnectionSource}.
|
||||
*/
|
||||
protected static class ContainerConnectionDetails implements ConnectionDetails, OriginProvider {
|
||||
|
||||
private final Origin origin;
|
||||
|
||||
/**
|
||||
* Create a new {@link ContainerConnectionDetails} instance.
|
||||
* @param source the source {@link ContainerConnectionSource}
|
||||
*/
|
||||
protected ContainerConnectionDetails(ContainerConnectionSource<?, ?, ?> source) {
|
||||
Assert.notNull(source, "Source must not be null");
|
||||
this.origin = source.getOrigin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Origin getOrigin() {
|
||||
return this.origin;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.service.connection;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.testcontainers.containers.GenericContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
|
||||
import org.springframework.boot.origin.Origin;
|
||||
import org.springframework.boot.origin.OriginProvider;
|
||||
import org.springframework.core.annotation.MergedAnnotation;
|
||||
|
||||
/**
|
||||
* Passed to {@link ContainerConnectionDetailsFactory} to provide details of the
|
||||
* {@link ServiceConnection @ServiceConnection} annotation {@link GenericContainer} field
|
||||
* that provides the service.
|
||||
*
|
||||
* @param <A> the source annotation type. The annotation will mergable to a
|
||||
* {@link ServiceConnection @ServiceConnection}
|
||||
* @param <D> the connection details type
|
||||
* @param <C> the generic container type
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
* @since 3.1.0
|
||||
* @see ContainerConnectionDetailsFactory
|
||||
*/
|
||||
public final class ContainerConnectionSource<A extends Annotation, D extends ConnectionDetails, C extends GenericContainer<?>>
|
||||
implements OriginProvider {
|
||||
|
||||
private final Class<D> connectionDetailsType;
|
||||
|
||||
private final Field field;
|
||||
|
||||
private final A annotation;
|
||||
|
||||
private final C container;
|
||||
|
||||
private final AnnotatedFieldOrigin origin;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ContainerConnectionSource(Class<D> connectionDetailsType, Field field,
|
||||
MergedAnnotation<ServiceConnection> annotation, C container) {
|
||||
this(connectionDetailsType, field, (A) annotation.getRoot().synthesize(), container);
|
||||
}
|
||||
|
||||
ContainerConnectionSource(Class<D> connectionDetailsType, Field field, A annotation, C container) {
|
||||
this.connectionDetailsType = connectionDetailsType;
|
||||
this.field = field;
|
||||
this.annotation = annotation;
|
||||
this.container = container;
|
||||
this.origin = new AnnotatedFieldOrigin(field, annotation);
|
||||
}
|
||||
|
||||
boolean accepts(Class<?> annotationType, Class<?> connectionDetailsType, Class<?> containerType) {
|
||||
return annotationType.isInstance(this.annotation)
|
||||
&& connectionDetailsType.isAssignableFrom(this.connectionDetailsType)
|
||||
&& containerType.isInstance(this.container);
|
||||
}
|
||||
|
||||
String getBeanName() {
|
||||
return this.field.getName() + this.connectionDetailsType.getSimpleName() + "ConnectedContainer";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the source annotation that provided the connection to the container. This
|
||||
* annotation will be mergable to {@link ServiceConnection @ServiceConnection}.
|
||||
* @return the source annotation
|
||||
*/
|
||||
public A getAnnotation() {
|
||||
return this.annotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link GenericContainer} that implements the service being connected to.
|
||||
* @return the {@link GenericContainer} providing the service
|
||||
*/
|
||||
public C getContainer() {
|
||||
return this.container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Origin getOrigin() {
|
||||
return this.origin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ServiceConnectedContainer for %s".formatted(this.origin);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.service.connection;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
|
||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory;
|
||||
|
||||
/**
|
||||
* Annotation used to indicate that a field provides a service that can be connected to.
|
||||
* Typically used to meta-annotate a higher-level annotation.
|
||||
* <p>
|
||||
* When used, a {@link ConnectionDetailsFactory} must be registered in
|
||||
* {@code spring.factories} to provide {@link ConnectionDetails} for the field value.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
* @since 3.1.0
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD, ElementType.ANNOTATION_TYPE })
|
||||
public @interface ServiceConnection {
|
||||
|
||||
/**
|
||||
* The type of {@link ConnectionDetails} that can describe how to connect to the
|
||||
* service.
|
||||
* @return the connection type
|
||||
*/
|
||||
Class<? extends ConnectionDetails> value();
|
||||
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.service.connection;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
|
||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactories;
|
||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.test.context.ContextCustomizer;
|
||||
import org.springframework.test.context.MergedContextConfiguration;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link ContextCustomizer} to support registering {@link ConnectionDetails}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ServiceConnectionContextCustomizer implements ContextCustomizer {
|
||||
|
||||
private final ConnectionDetailsFactories factories = new ConnectionDetailsFactories();
|
||||
|
||||
private final List<ContainerConnectionSource<?, ?, ?>> sources;
|
||||
|
||||
ServiceConnectionContextCustomizer(List<ContainerConnectionSource<?, ?, ?>> sources) {
|
||||
this.sources = sources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
|
||||
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
|
||||
if (beanFactory instanceof BeanDefinitionRegistry registry) {
|
||||
registerServiceConnections(registry);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerServiceConnections(BeanDefinitionRegistry registry) {
|
||||
this.sources.forEach((source) -> registerServiceConnection(registry, source));
|
||||
}
|
||||
|
||||
private void registerServiceConnection(BeanDefinitionRegistry registry, ContainerConnectionSource<?, ?, ?> source) {
|
||||
ConnectionDetails connectionDetails = getConnectionDetails(source);
|
||||
String beanName = source.getBeanName();
|
||||
registry.registerBeanDefinition(beanName, createBeanDefinition(connectionDetails));
|
||||
}
|
||||
|
||||
private <S> ConnectionDetails getConnectionDetails(S source) {
|
||||
ConnectionDetailsFactory<S, ConnectionDetails> factory = this.factories.getConnectionDetailsFactory(source);
|
||||
ConnectionDetails connectionDetails = factory.getConnectionDetails(source);
|
||||
Assert.state(connectionDetails != null,
|
||||
() -> "No connection details created by %s".formatted(factory.getClass().getName()));
|
||||
return connectionDetails;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> BeanDefinition createBeanDefinition(T instance) {
|
||||
return new RootBeanDefinition((Class<T>) instance.getClass(), () -> instance);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.service.connection;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.testcontainers.containers.GenericContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
|
||||
import org.springframework.core.annotation.MergedAnnotation;
|
||||
import org.springframework.core.annotation.MergedAnnotations;
|
||||
import org.springframework.test.context.ContextConfigurationAttributes;
|
||||
import org.springframework.test.context.ContextCustomizer;
|
||||
import org.springframework.test.context.ContextCustomizerFactory;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* {@link ContextCustomizerFactory} to support service connections in tests.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ServiceConnectionContextCustomizerFactory implements ContextCustomizerFactory {
|
||||
|
||||
@Override
|
||||
public ContextCustomizer createContextCustomizer(Class<?> testClass,
|
||||
List<ContextConfigurationAttributes> configAttributes) {
|
||||
List<ContainerConnectionSource<?, ?, ?>> sources = new ArrayList<>();
|
||||
ReflectionUtils.doWithFields(testClass, (field) -> {
|
||||
MergedAnnotations annotations = MergedAnnotations.from(field);
|
||||
annotations.stream(ServiceConnection.class)
|
||||
.forEach((annotation) -> sources.add(createSource(field, annotation)));
|
||||
});
|
||||
return (sources.isEmpty()) ? null : new ServiceConnectionContextCustomizer(sources);
|
||||
}
|
||||
|
||||
private ContainerConnectionSource<?, ?, ?> createSource(Field field,
|
||||
MergedAnnotation<ServiceConnection> annotation) {
|
||||
Class<? extends ConnectionDetails> connectionDetailsType = getConnectionDetailsType(annotation);
|
||||
Object fieldValue = getFieldValue(field);
|
||||
Assert.isInstanceOf(GenericContainer.class, fieldValue,
|
||||
"Field %s must be a %s".formatted(field.getName(), GenericContainer.class.getName()));
|
||||
GenericContainer<?> container = (GenericContainer<?>) fieldValue;
|
||||
return new ContainerConnectionSource<>(connectionDetailsType, field, annotation, container);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Class<? extends ConnectionDetails> getConnectionDetailsType(
|
||||
MergedAnnotation<ServiceConnection> annotation) {
|
||||
return (Class<? extends ConnectionDetails>) annotation.getClass(MergedAnnotation.VALUE);
|
||||
}
|
||||
|
||||
private Object getFieldValue(Field field) {
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
return ReflectionUtils.getField(field, null);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* General support for auto-configuration of service connections in tests.
|
||||
*/
|
||||
package org.springframework.boot.test.autoconfigure.service.connection;
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.amqp;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.awaitility.Awaitility;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.testcontainers.containers.RabbitMQContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import org.springframework.amqp.rabbit.annotation.Queue;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.amqp.RabbitServiceConnectionTests.TestConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link RabbitServiceConnection}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@SpringBootTest(classes = TestConfiguration.class)
|
||||
@Testcontainers(disabledWithoutDocker = true)
|
||||
class RabbitServiceConnectionTests {
|
||||
|
||||
@Container
|
||||
@RabbitServiceConnection
|
||||
static final RabbitMQContainer rabbit = new RabbitMQContainer(DockerImageNames.rabbit());
|
||||
|
||||
@Autowired
|
||||
RabbitTemplate rabbitTemplate;
|
||||
|
||||
@Autowired
|
||||
TestListener listener;
|
||||
|
||||
@Test
|
||||
void connectionCanBeMadeToKafkaContainer() {
|
||||
this.rabbitTemplate.convertAndSend("test", "message");
|
||||
Awaitility.waitAtMost(Duration.ofSeconds(30))
|
||||
.untilAsserted(() -> assertThat(this.listener.messages).containsExactly("message"));
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration(RabbitAutoConfiguration.class)
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
TestListener testListener() {
|
||||
return new TestListener();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class TestListener {
|
||||
|
||||
private final List<String> messages = new ArrayList<>();
|
||||
|
||||
@RabbitListener(queuesToDeclare = @Queue("test"))
|
||||
void processMessage(String message) {
|
||||
this.messages.add(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.influx;
|
||||
|
||||
import org.influxdb.InfluxDB;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.testcontainers.containers.InfluxDBContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.influx.InfluxDbServiceConnectionTests.TestConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link InfluxDbServiceConnection}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@SpringBootTest(classes = TestConfiguration.class)
|
||||
@Testcontainers(disabledWithoutDocker = true)
|
||||
class InfluxDbServiceConnectionTests {
|
||||
|
||||
@Container
|
||||
@InfluxDbServiceConnection
|
||||
static final InfluxDBContainer<?> influxDbService = new InfluxDBContainer<>(DockerImageNames.influxDb());
|
||||
|
||||
@Autowired
|
||||
InfluxDB influxDb;
|
||||
|
||||
@Test
|
||||
void connectionCanBeMadeToInfluxDbContainer() {
|
||||
assertThat(this.influxDb.version()).isEqualTo("v" + DockerImageNames.influxDb().getVersionPart());
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration(InfluxDbAutoConfiguration.class)
|
||||
static class TestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.test.autoconfigure.kafka;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.awaitility.Awaitility;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.testcontainers.containers.KafkaContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.kafka.KafkaServiceConnectionTests.TestConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.kafka.annotation.KafkaListener;
|
||||
import org.springframework.kafka.core.KafkaTemplate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link KafkaServiceConnection}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@SpringBootTest(classes = TestConfiguration.class,
|
||||
properties = { "spring.kafka.consumer.group-id=test-group",
|
||||
"spring.kafka.consumer.auto-offset-reset=earliest" })
|
||||
@Testcontainers(disabledWithoutDocker = true)
|
||||
class KafkaServiceConnectionTests {
|
||||
|
||||
@Container
|
||||
@KafkaServiceConnection
|
||||
static final KafkaContainer kafka = new KafkaContainer(DockerImageNames.kafka());
|
||||
|
||||
@Autowired
|
||||
KafkaTemplate<String, String> kafkaTemplate;
|
||||
|
||||
@Autowired
|
||||
TestListener listener;
|
||||
|
||||
@Test
|
||||
void connectionCanBeMadeToKafkaContainer() {
|
||||
this.kafkaTemplate.send("test-topic", "test-data");
|
||||
Awaitility.waitAtMost(Duration.ofSeconds(30))
|
||||
.untilAsserted(() -> assertThat(this.listener.messages).containsExactly("test-data"));
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration(KafkaAutoConfiguration.class)
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
TestListener testListener() {
|
||||
return new TestListener();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class TestListener {
|
||||
|
||||
private final List<String> messages = new ArrayList<>();
|
||||
|
||||
@KafkaListener(topics = "test-topic")
|
||||
void processMessage(String message) {
|
||||
this.messages.add(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue