diff --git a/pom.xml b/pom.xml index 2c1b63687b2..11b6afa0d1c 100644 --- a/pom.xml +++ b/pom.xml @@ -267,7 +267,7 @@ ${java.version} - 3.5.0 + 3.5.1 4.3.4 1.0.0-beta.16 1.1.0 diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/testcontainers.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/testcontainers.adoc index 9d262062fe1..7a01d7088e2 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/testcontainers.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/testcontainers.adoc @@ -38,6 +38,9 @@ The following service connection factories are provided in the `spring-ai-spring | `ChromaConnectionDetails` | Containers of type `ChromaDBContainer` +| `McpSseClientConnectionDetails` +| Containers of type `DockerMcpGatewayContainer` + | `MilvusServiceClientConnectionDetails` | Containers of type `MilvusContainer` diff --git a/spring-ai-spring-boot-testcontainers/pom.xml b/spring-ai-spring-boot-testcontainers/pom.xml index f529958eaa3..0823a1623ef 100644 --- a/spring-ai-spring-boot-testcontainers/pom.xml +++ b/spring-ai-spring-boot-testcontainers/pom.xml @@ -101,6 +101,20 @@ true + + org.springframework.ai + spring-ai-autoconfigure-mcp-client-httpclient + ${project.version} + true + + + + org.springframework.ai + spring-ai-autoconfigure-mcp-client-webflux + ${project.version} + true + + @@ -239,6 +253,7 @@ org.testcontainers testcontainers + 1.21.3 true diff --git a/spring-ai-spring-boot-testcontainers/src/main/java/org/springframework/ai/testcontainers/service/connection/docker/DockerMcpGatewayContainerConnectionDetailsFactory.java b/spring-ai-spring-boot-testcontainers/src/main/java/org/springframework/ai/testcontainers/service/connection/docker/DockerMcpGatewayContainerConnectionDetailsFactory.java new file mode 100644 index 00000000000..72053708e3c --- /dev/null +++ b/spring-ai-spring-boot-testcontainers/src/main/java/org/springframework/ai/testcontainers/service/connection/docker/DockerMcpGatewayContainerConnectionDetailsFactory.java @@ -0,0 +1,59 @@ +/* + * Copyright 2023-2025 the original author 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.ai.testcontainers.service.connection.docker; + +import java.util.Map; + +import org.testcontainers.containers.DockerMcpGatewayContainer; + +import org.springframework.ai.mcp.client.common.autoconfigure.McpSseClientConnectionDetails; +import org.springframework.ai.mcp.client.common.autoconfigure.properties.McpSseClientProperties; +import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; +import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; + +/** + * @author EddĂș MelĂ©ndez + */ +class DockerMcpGatewayContainerConnectionDetailsFactory + extends ContainerConnectionDetailsFactory { + + @Override + public McpSseClientConnectionDetails getContainerConnectionDetails( + ContainerConnectionSource source) { + return new DockerMcpGatewayContainerConnectionDetails(source); + } + + /** + * {@link McpSseClientConnectionDetails} backed by a + * {@link ContainerConnectionSource}. + */ + private static final class DockerMcpGatewayContainerConnectionDetails + extends ContainerConnectionDetails implements McpSseClientConnectionDetails { + + private DockerMcpGatewayContainerConnectionDetails( + ContainerConnectionSource source) { + super(source); + } + + @Override + public Map getConnections() { + return Map.of("gateway", new McpSseClientProperties.SseParameters(getContainer().getEndpoint(), "/sse")); + } + + } + +} diff --git a/spring-ai-spring-boot-testcontainers/src/main/resources/META-INF/spring.factories b/spring-ai-spring-boot-testcontainers/src/main/resources/META-INF/spring.factories index 19576a7a6f4..d2573340aa4 100644 --- a/spring-ai-spring-boot-testcontainers/src/main/resources/META-INF/spring.factories +++ b/spring-ai-spring-boot-testcontainers/src/main/resources/META-INF/spring.factories @@ -15,6 +15,7 @@ # org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\ org.springframework.ai.testcontainers.service.connection.chroma.ChromaContainerConnectionDetailsFactory,\ +org.springframework.ai.testcontainers.service.connection.docker.DockerMcpGatewayContainerConnectionDetailsFactory,\ org.springframework.ai.testcontainers.service.connection.milvus.MilvusContainerConnectionDetailsFactory,\ org.springframework.ai.testcontainers.service.connection.mongo.MongoDbAtlasLocalContainerConnectionDetailsFactory,\ org.springframework.ai.testcontainers.service.connection.ollama.OllamaContainerConnectionDetailsFactory,\ diff --git a/spring-ai-spring-boot-testcontainers/src/test/java/org/springframework/ai/testcontainers/service/connection/docker/DockerMcpGatewayContainerConnectionDetailsFactoryIT.java b/spring-ai-spring-boot-testcontainers/src/test/java/org/springframework/ai/testcontainers/service/connection/docker/DockerMcpGatewayContainerConnectionDetailsFactoryIT.java new file mode 100644 index 00000000000..1b87922cf65 --- /dev/null +++ b/spring-ai-spring-boot-testcontainers/src/test/java/org/springframework/ai/testcontainers/service/connection/docker/DockerMcpGatewayContainerConnectionDetailsFactoryIT.java @@ -0,0 +1,58 @@ +/* + * Copyright 2023-2025 the original author 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.ai.testcontainers.service.connection.docker; + +import org.junit.jupiter.api.Test; +import org.testcontainers.containers.DockerMcpGatewayContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import org.springframework.ai.mcp.client.common.autoconfigure.McpSseClientConnectionDetails; +import org.springframework.ai.mcp.client.common.autoconfigure.properties.McpSseClientProperties; +import org.springframework.ai.mcp.client.httpclient.autoconfigure.SseHttpClientTransportAutoConfiguration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.testcontainers.service.connection.ServiceConnection; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringJUnitConfig +@Testcontainers +class DockerMcpGatewayContainerConnectionDetailsFactoryIT { + + @Container + @ServiceConnection + private static final DockerMcpGatewayContainer MCP_GATEWAY = new DockerMcpGatewayContainer("docker/mcp-gateway:v2"); + + @Autowired + private McpSseClientConnectionDetails connectionDetails; + + @Test + void test() { + assertThat(this.connectionDetails.getConnections()).containsEntry("gateway", + new McpSseClientProperties.SseParameters(MCP_GATEWAY.getEndpoint(), "/sse")); + } + + @Configuration(proxyBeanMethods = false) + @ImportAutoConfiguration(SseHttpClientTransportAutoConfiguration.class) + static class Config { + + } + +}