diff --git a/start-site/src/main/java/io/spring/start/site/container/SimpleDockerServiceResolver.java b/start-site/src/main/java/io/spring/start/site/container/SimpleDockerServiceResolver.java index ef615d37e5e..8e75364f5bd 100644 --- a/start-site/src/main/java/io/spring/start/site/container/SimpleDockerServiceResolver.java +++ b/start-site/src/main/java/io/spring/start/site/container/SimpleDockerServiceResolver.java @@ -50,6 +50,7 @@ public SimpleDockerServiceResolver() { this.dockerServices.put("pulsar", pulsar()); this.dockerServices.put("rabbit", rabbit()); this.dockerServices.put("redis", redis()); + this.dockerServices.put("redisStack", redisStack()); this.dockerServices.put("sqlServer", sqlServer()); this.dockerServices.put("zipkin", zipkin()); } @@ -153,6 +154,13 @@ private static DockerService redis() { return DockerService.withImageAndTag("redis").website("https://hub.docker.com/_/redis").ports(6379).build(); } + private static DockerService redisStack() { + return DockerService.withImageAndTag("redis/redis-stack") + .website("https://hub.docker.com/r/redis/redis-stack") + .ports(6379) + .build(); + } + private static DockerService sqlServer() { return DockerService.withImageAndTag("mcr.microsoft.com/mssql/server") .website("https://mcr.microsoft.com/en-us/product/mssql/server/about/") diff --git a/start-site/src/main/java/io/spring/start/site/extension/dependency/redis/RedisStackProjectGenerationConfiguration.java b/start-site/src/main/java/io/spring/start/site/extension/dependency/redis/RedisStackProjectGenerationConfiguration.java new file mode 100644 index 00000000000..679f5c4d55b --- /dev/null +++ b/start-site/src/main/java/io/spring/start/site/extension/dependency/redis/RedisStackProjectGenerationConfiguration.java @@ -0,0 +1,52 @@ +/* + * Copyright 2012-2024 the original author 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 io.spring.start.site.extension.dependency.redis; + +import io.spring.initializr.generator.condition.ConditionalOnRequestedDependency; +import io.spring.start.site.container.ComposeFileCustomizer; +import io.spring.start.site.container.DockerServiceResolver; +import io.spring.start.site.container.ServiceConnections.ServiceConnection; +import io.spring.start.site.container.ServiceConnectionsCustomizer; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Configuration for generation of projects that depend on Redis Stack. + * + * @author Eddú Meléndez + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnRequestedDependency("spring-ai-vectordb-redis") +class RedisStackProjectGenerationConfiguration { + + @Bean + @ConditionalOnRequestedDependency("testcontainers") + ServiceConnectionsCustomizer redisStackServiceConnectionsCustomizer(DockerServiceResolver serviceResolver) { + return (serviceConnections) -> serviceResolver.doWith("redisStack", (service) -> serviceConnections + .addServiceConnection(ServiceConnection.ofGenericContainer("redisStack", service, "redis"))); + } + + @Bean + @ConditionalOnRequestedDependency("docker-compose") + ComposeFileCustomizer redisStackComposeFileCustomizer(DockerServiceResolver serviceResolver) { + return (composeFile) -> serviceResolver.doWith("redisStack", (service) -> composeFile.services() + .add("redis", + service.andThen(builder -> builder.label("org.springframework.boot.service-connection", "redis")))); + } + +} diff --git a/start-site/src/main/resources/META-INF/spring.factories b/start-site/src/main/resources/META-INF/spring.factories index 40924849fc3..d5c145a717b 100644 --- a/start-site/src/main/resources/META-INF/spring.factories +++ b/start-site/src/main/resources/META-INF/spring.factories @@ -24,6 +24,7 @@ io.spring.start.site.extension.dependency.oracle.OracleProjectGenerationConfigur io.spring.start.site.extension.dependency.postgresql.PgVectorProjectGenerationConfiguration,\ io.spring.start.site.extension.dependency.postgresql.PostgresqlProjectGenerationConfiguration,\ io.spring.start.site.extension.dependency.redis.RedisProjectGenerationConfiguration,\ +io.spring.start.site.extension.dependency.redis.RedisStackProjectGenerationConfiguration,\ io.spring.start.site.extension.dependency.sbom.SbomProjectGenerationConfiguration,\ io.spring.start.site.extension.dependency.solace.SolaceProjectGenerationConfiguration,\ io.spring.start.site.extension.dependency.springamqp.SpringAmqpProjectGenerationConfiguration,\ diff --git a/start-site/src/test/java/io/spring/start/site/extension/dependency/redis/RedisStackProjectGenerationConfigurationTests.java b/start-site/src/test/java/io/spring/start/site/extension/dependency/redis/RedisStackProjectGenerationConfigurationTests.java new file mode 100644 index 00000000000..0d511148081 --- /dev/null +++ b/start-site/src/test/java/io/spring/start/site/extension/dependency/redis/RedisStackProjectGenerationConfigurationTests.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2024 the original author 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 io.spring.start.site.extension.dependency.redis; + +import io.spring.initializr.generator.test.project.ProjectStructure; +import io.spring.initializr.web.project.ProjectRequest; +import io.spring.start.site.extension.AbstractExtensionTests; +import org.junit.jupiter.api.Test; +import org.springframework.core.io.ClassPathResource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link RedisStackProjectGenerationConfiguration}. + * + * @author Eddú Meléndez + */ +class RedisStackProjectGenerationConfigurationTests extends AbstractExtensionTests { + + @Test + void doesNothingWithoutDockerCompose() { + ProjectRequest request = createProjectRequest("spring-ai-vectordb-redis"); + ProjectStructure structure = generateProject(request); + assertThat(structure.getProjectDirectory().resolve("compose.yaml")).doesNotExist(); + } + + @Test + void createsRedisStackService() { + ProjectRequest request = createProjectRequest("docker-compose", "spring-ai-vectordb-redis"); + assertThat(composeFile(request)).hasSameContentAs(new ClassPathResource("compose/redis-stack.yaml")); + } + +} diff --git a/start-site/src/test/resources/compose/redis-stack.yaml b/start-site/src/test/resources/compose/redis-stack.yaml new file mode 100644 index 00000000000..2b232704876 --- /dev/null +++ b/start-site/src/test/resources/compose/redis-stack.yaml @@ -0,0 +1,7 @@ +services: + redis: + image: 'redis/redis-stack:latest' + labels: + - "org.springframework.boot.service-connection=redis" + ports: + - '6379'