Skip to content

Commit 852ffbd

Browse files
eddumelendezmhalbritter
authored andcommitted
Generate test application with pgvector and spring-ai if pgvector is selected
See gh-1420
1 parent 9fde8e4 commit 852ffbd

File tree

7 files changed

+162
-8
lines changed

7 files changed

+162
-8
lines changed

start-site/src/main/java/io/spring/start/site/container/SimpleDockerServiceResolver.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public SimpleDockerServiceResolver() {
4646
this.dockerServices.put("neo4j", neo4j());
4747
this.dockerServices.put("oracleFree", oracleFree());
4848
this.dockerServices.put("oracleXe", oracleXe());
49+
this.dockerServices.put("pgvector", pgvector());
4950
this.dockerServices.put("postgres", postgres());
5051
this.dockerServices.put("pulsar", pulsar());
5152
this.dockerServices.put("rabbit", rabbit());
@@ -127,6 +128,13 @@ private static DockerService oracleXe() {
127128
.build();
128129
}
129130

131+
private static DockerService pgvector() {
132+
return DockerService.withImageAndTag("pgvector/pgvector:pg16")
133+
.website("https://hub.docker.com/r/pgvector/pgvector")
134+
.ports(5432)
135+
.build();
136+
}
137+
130138
private static DockerService postgres() {
131139
return DockerService.withImageAndTag("postgres")
132140
.website("https://hub.docker.com/_/postgres")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright 2012-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.spring.start.site.extension.dependency.postgresql;
18+
19+
import java.util.Map;
20+
21+
import io.spring.initializr.generator.condition.ConditionalOnRequestedDependency;
22+
import io.spring.initializr.generator.project.ProjectDescription;
23+
import io.spring.initializr.generator.version.Version;
24+
import io.spring.initializr.generator.version.VersionParser;
25+
import io.spring.initializr.generator.version.VersionRange;
26+
import io.spring.initializr.versionresolver.MavenVersionResolver;
27+
import io.spring.start.site.container.ComposeFileCustomizer;
28+
import io.spring.start.site.container.DockerServiceResolver;
29+
import io.spring.start.site.container.ServiceConnections.ServiceConnection;
30+
import io.spring.start.site.container.ServiceConnectionsCustomizer;
31+
32+
import org.springframework.context.annotation.Bean;
33+
import org.springframework.context.annotation.Configuration;
34+
35+
/**
36+
* Configuration for generation of projects that depend on PgVector.
37+
*
38+
* @author Eddú Meléndez
39+
*/
40+
@Configuration(proxyBeanMethods = false)
41+
@ConditionalOnRequestedDependency("spring-ai-vectordb-pgvector")
42+
class PgVectorProjectGenerationConfiguration {
43+
44+
private static final String TESTCONTAINERS_CLASS_NAME = "org.testcontainers.containers.PostgreSQLContainer";
45+
46+
private static final VersionRange TESTCONTAINERS_1_19_7_OR_LATER = VersionParser.DEFAULT.parseRange("1.19.7");
47+
48+
private final MavenVersionResolver versionResolver;
49+
50+
private final ProjectDescription description;
51+
52+
PgVectorProjectGenerationConfiguration(MavenVersionResolver versionResolver, ProjectDescription description) {
53+
this.versionResolver = versionResolver;
54+
this.description = description;
55+
}
56+
57+
@Bean
58+
@ConditionalOnRequestedDependency("testcontainers")
59+
ServiceConnectionsCustomizer pgvectorServiceConnectionsCustomizer(DockerServiceResolver serviceResolver) {
60+
Map<String, String> resolve = this.versionResolver.resolveDependencies("org.springframework.boot",
61+
"spring-boot-dependencies", this.description.getPlatformVersion().toString());
62+
String testcontainersVersion = resolve.get("org.testcontainers:testcontainers");
63+
64+
return (serviceConnections) -> {
65+
if (TESTCONTAINERS_1_19_7_OR_LATER.match(Version.parse(testcontainersVersion))) {
66+
serviceResolver.doWith("pgvector", (service) -> serviceConnections.addServiceConnection(
67+
ServiceConnection.ofContainer("pgvector", service, TESTCONTAINERS_CLASS_NAME)));
68+
}
69+
};
70+
}
71+
72+
@Bean
73+
@ConditionalOnRequestedDependency("docker-compose")
74+
ComposeFileCustomizer pgvectorComposeFileCustomizer(DockerServiceResolver serviceResolver) {
75+
return (composeFile) -> serviceResolver.doWith("pgvector",
76+
(service) -> composeFile.services()
77+
.add("pgvector",
78+
service.andThen((builder) -> builder.environment("POSTGRES_USER", "myuser")
79+
.environment("POSTGRES_DB", "mydatabase")
80+
.environment("POSTGRES_PASSWORD", "secret")
81+
.label("org.springframework.boot.service-connection", "postgres"))));
82+
}
83+
84+
}

start-site/src/main/java/io/spring/start/site/extension/dependency/testcontainers/TestcontainersModuleRegistry.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ static Iterable<ImplicitDependency> create(Version platformVersion) {
8888
builders.add(onDependencies("oracle").customizeBuild(addModule("oracle-xe"))
8989
.customizeHelpDocument(addReferenceLink("Oracle-XE Module", "databases/oraclexe/")));
9090
}
91-
builders.add(onDependencies("postgresql").customizeBuild(addModule("postgresql"))
91+
builders.add(onDependencies("postgresql", "spring-ai-vectordb-pgvector").customizeBuild(addModule("postgresql"))
9292
.customizeHelpDocument(addReferenceLink("Postgres Module", "databases/postgres/")));
9393
builders.add(onDependencies("pulsar", "pulsar-reactive").customizeBuild(addModule("pulsar"))
9494
.customizeHelpDocument(addReferenceLink("Pulsar Module", "pulsar/")));

start-site/src/main/resources/META-INF/spring.factories

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ io.spring.start.site.extension.dependency.neo4j.Neo4jProjectGenerationConfigurat
2121
io.spring.start.site.extension.dependency.observability.ObservabilityProjectGenerationConfiguration,\
2222
io.spring.start.site.extension.dependency.oracle.OracleProjectGenerationConfiguration,\
2323
io.spring.start.site.extension.dependency.picocli.PicocliProjectGenerationConfiguration,\
24+
io.spring.start.site.extension.dependency.postgresql.PgVectorProjectGenerationConfiguration,\
2425
io.spring.start.site.extension.dependency.postgresql.PostgresqlProjectGenerationConfiguration,\
2526
io.spring.start.site.extension.dependency.redis.RedisProjectGenerationConfiguration,\
2627
io.spring.start.site.extension.dependency.solace.SolaceProjectGenerationConfiguration,\
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2012-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.spring.start.site.extension.dependency.postgresql;
18+
19+
import io.spring.initializr.generator.test.project.ProjectStructure;
20+
import io.spring.initializr.web.project.ProjectRequest;
21+
import io.spring.start.site.extension.AbstractExtensionTests;
22+
import org.junit.jupiter.api.Test;
23+
24+
import org.springframework.core.io.ClassPathResource;
25+
26+
import static org.assertj.core.api.Assertions.assertThat;
27+
28+
/**
29+
* Tests for {@link PgVectorProjectGenerationConfiguration}.
30+
*
31+
* @author Eddú Meléndez
32+
*/
33+
class PgVectorProjectGenerationConfigurationTests extends AbstractExtensionTests {
34+
35+
@Test
36+
void doesNothingWithoutDockerCompose() {
37+
ProjectRequest request = createProjectRequest("web", "spring-ai-vectordb-pgvector");
38+
ProjectStructure structure = generateProject(request);
39+
assertThat(structure.getProjectDirectory().resolve("compose.yaml")).doesNotExist();
40+
}
41+
42+
@Test
43+
void createsPostgresService() {
44+
ProjectRequest request = createProjectRequest("docker-compose", "spring-ai-vectordb-pgvector");
45+
assertThat(composeFile(request)).hasSameContentAs(new ClassPathResource("compose/pgvector.yaml"));
46+
}
47+
48+
}

start-site/src/test/java/io/spring/start/site/extension/dependency/testcontainers/TestcontainersProjectGenerationConfigurationTests.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,15 @@ static Stream<Arguments> supportedEntriesBuild() {
8585
Arguments.arguments("data-couchbase-reactive", "couchbase"),
8686
Arguments.arguments("data-elasticsearch", "elasticsearch"),
8787
Arguments.arguments("data-mongodb", "mongodb"), Arguments.arguments("data-mongodb-reactive", "mongodb"),
88-
Arguments.arguments("data-neo4j", "neo4j"), Arguments.arguments("spring-ai-vectordb-neo4j", "neo4j"),
89-
Arguments.arguments("data-r2dbc", "r2dbc"), Arguments.arguments("db2", "db2"),
90-
Arguments.arguments("kafka", "kafka"), Arguments.arguments("kafka-streams", "kafka"),
91-
Arguments.arguments("mariadb", "mariadb"), Arguments.arguments("mysql", "mysql"),
92-
Arguments.arguments("postgresql", "postgresql"), Arguments.arguments("oracle", "oracle-xe"),
93-
Arguments.arguments("pulsar", "pulsar"), Arguments.arguments("pulsar-reactive", "pulsar"),
94-
Arguments.arguments("solace", "solace"), Arguments.arguments("sqlserver", "mssqlserver"));
88+
Arguments.arguments("data-neo4j", "neo4j"), Arguments.arguments("data-r2dbc", "r2dbc"),
89+
Arguments.arguments("db2", "db2"), Arguments.arguments("kafka", "kafka"),
90+
Arguments.arguments("kafka-streams", "kafka"), Arguments.arguments("mariadb", "mariadb"),
91+
Arguments.arguments("mysql", "mysql"), Arguments.arguments("postgresql", "postgresql"),
92+
Arguments.arguments("oracle", "oracle-xe"), Arguments.arguments("pulsar", "pulsar"),
93+
Arguments.arguments("pulsar-reactive", "pulsar"), Arguments.arguments("solace", "solace"),
94+
Arguments.arguments("spring-ai-vectordb-neo4j", "neo4j"),
95+
Arguments.arguments("spring-ai-vectordb-pgvector", "postgresql"),
96+
Arguments.arguments("sqlserver", "mssqlserver"));
9597
}
9698

9799
static Stream<Arguments> supportedTestcontainersActiveMQEntriesBuild() {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
services:
2+
pgvector:
3+
image: 'pgvector/pgvector:pg16'
4+
environment:
5+
- 'POSTGRES_DB=mydatabase'
6+
- 'POSTGRES_PASSWORD=secret'
7+
- 'POSTGRES_USER=myuser'
8+
labels:
9+
- "org.springframework.boot.service-connection=postgres"
10+
ports:
11+
- '5432'

0 commit comments

Comments
 (0)