Skip to content

Commit

Permalink
Polish "Generate test apps for spring-ai projects"
Browse files Browse the repository at this point in the history
  • Loading branch information
mhalbritter committed Sep 5, 2024
1 parent 25f4998 commit f114449
Show file tree
Hide file tree
Showing 15 changed files with 260 additions and 156 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 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.springai;

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 io.spring.initializr.generator.project.ProjectDescription;

import org.springframework.context.annotation.Conditional;

/**
* Condition that matches when a {@link ProjectDescription} defines a dependency on Spring
* AI. A generated project may ultimately define a different set of dependencies according
* to the contributors that have been executed. To contribute to the project according to
* the real set, prefer querying the model itself rather than using this condition.
*
* @author Moritz Halbritter
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnRequestedSpringAiDependencyCondition.class)
@interface ConditionalOnRequestedSpringAiDependency {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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.springai;

import io.spring.initializr.generator.buildsystem.Dependency;
import io.spring.initializr.generator.condition.ProjectGenerationCondition;
import io.spring.initializr.generator.project.ProjectDescription;

import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

/**
* {@link ProjectGenerationCondition} implementation for
* {@link ConditionalOnRequestedSpringAiDependency}.
*
* @author Moritz Halbritter
*/
class OnRequestedSpringAiDependencyCondition extends ProjectGenerationCondition {

@Override
protected boolean matches(ProjectDescription description, ConditionContext context,
AnnotatedTypeMetadata metadata) {
for (Dependency dependency : description.getRequestedDependencies().values()) {
if (dependency.getGroupId().equals("org.springframework.ai")) {
return true;
}
}
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
package io.spring.start.site.extension.dependency.springai;

import io.spring.initializr.generator.condition.ConditionalOnRequestedDependency;
import io.spring.initializr.generator.project.ProjectDescription;
import io.spring.initializr.generator.project.ProjectGenerationConfiguration;
import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.start.site.container.ComposeFileCustomizer;
import io.spring.start.site.container.DockerServiceResolver;
import io.spring.start.site.container.ServiceConnections.ServiceConnection;
Expand All @@ -40,25 +38,16 @@ class SpringAiChromaProjectGenerationConfiguration {

@Bean
@ConditionalOnRequestedDependency("testcontainers")
ServiceConnectionsCustomizer chromaServiceConnectionsCustomizer(InitializrMetadata metadata,
ProjectDescription description, DockerServiceResolver serviceResolver) {
return (serviceConnections) -> {
if (SpringAiVersion.version1OrLater(metadata, description.getPlatformVersion())) {
serviceResolver.doWith("chroma", (service) -> serviceConnections
.addServiceConnection(ServiceConnection.ofContainer("chroma", service, TESTCONTAINERS_CLASS_NAME)));
}
};
ServiceConnectionsCustomizer chromaServiceConnectionsCustomizer(DockerServiceResolver serviceResolver) {
return (serviceConnections) -> serviceResolver.doWith("chroma", (service) -> serviceConnections
.addServiceConnection(ServiceConnection.ofContainer("chroma", service, TESTCONTAINERS_CLASS_NAME, false)));
}

@Bean
@ConditionalOnRequestedDependency("docker-compose")
ComposeFileCustomizer chromaComposeFileCustomizer(InitializrMetadata metadata, ProjectDescription description,
DockerServiceResolver serviceResolver) {
return (composeFile) -> {
if (SpringAiVersion.version1OrLater(metadata, description.getPlatformVersion())) {
serviceResolver.doWith("chroma", (service) -> composeFile.services().add("chroma", service));
}
};
ComposeFileCustomizer chromaComposeFileCustomizer(DockerServiceResolver serviceResolver) {
return (composeFile) -> serviceResolver.doWith("chroma",
(service) -> composeFile.services().add("chroma", service));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import io.spring.initializr.generator.project.ProjectDescription;
import io.spring.initializr.generator.project.ProjectGenerationConfiguration;
import io.spring.initializr.generator.spring.build.BuildCustomizer;
import io.spring.initializr.generator.version.VersionProperty;
import io.spring.initializr.generator.version.VersionReference;
import io.spring.initializr.metadata.InitializrMetadata;

import org.springframework.context.annotation.Bean;
Expand All @@ -34,19 +36,30 @@
*/
@ProjectGenerationConfiguration
@ConditionalOnRequestedDependency("docker-compose")
class SpringAiDockerComposeProjectGenerationConfiguration {
@ConditionalOnRequestedSpringAiDependency
public class SpringAiDockerComposeProjectGenerationConfiguration {

/**
* Dependency id of
* {@code org.springframework.ai:spring-ai-spring-boot-docker-compose}.
*/
public static final String DEPENDENCY_ID = "spring-ai-docker-compose";

@Bean
BuildCustomizer<Build> springAiDockerComposeBuildCustomizer(InitializrMetadata metadata,
ProjectDescription description) {
return (build) -> {
if (SpringAiVersion.version1OrLater(metadata, description.getPlatformVersion())) {
build.dependencies()
.add("spring-ai-docker-compose",
Dependency.withCoordinates("org.springframework.ai", "spring-ai-spring-boot-docker-compose")
.scope(DependencyScope.TEST_COMPILE));
}
};
// spring-ai-spring-boot-docker-compose is not managed in the BOM
// See https://github.com/spring-projects/spring-ai/issues/1314
VersionProperty springAiBomVersion = getSpringAiVersion(metadata, description);
return (build) -> build.dependencies()
.add(DEPENDENCY_ID,
Dependency.withCoordinates("org.springframework.ai", "spring-ai-spring-boot-docker-compose")
.version(VersionReference.ofProperty(springAiBomVersion))
.scope(DependencyScope.RUNTIME));
}

private static VersionProperty getSpringAiVersion(InitializrMetadata metadata, ProjectDescription description) {
return metadata.getConfiguration().getEnv().getBoms().get("spring-ai").getVersionProperty();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
package io.spring.start.site.extension.dependency.springai;

import io.spring.initializr.generator.condition.ConditionalOnRequestedDependency;
import io.spring.initializr.generator.project.ProjectDescription;
import io.spring.initializr.generator.project.ProjectGenerationConfiguration;
import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.start.site.container.DockerServiceResolver;
import io.spring.start.site.container.ServiceConnections.ServiceConnection;
import io.spring.start.site.container.ServiceConnectionsCustomizer;
Expand All @@ -39,14 +37,9 @@ class SpringAiMilvusProjectGenerationConfiguration {

@Bean
@ConditionalOnRequestedDependency("testcontainers")
ServiceConnectionsCustomizer milvusServiceConnectionsCustomizer(InitializrMetadata metadata,
ProjectDescription description, DockerServiceResolver serviceResolver) {
return (serviceConnections) -> {
if (SpringAiVersion.version1OrLater(metadata, description.getPlatformVersion())) {
serviceResolver.doWith("milvus", (service) -> serviceConnections
.addServiceConnection(ServiceConnection.ofContainer("milvus", service, TESTCONTAINERS_CLASS_NAME)));
}
};
ServiceConnectionsCustomizer milvusServiceConnectionsCustomizer(DockerServiceResolver serviceResolver) {
return (serviceConnections) -> serviceResolver.doWith("milvus", (service) -> serviceConnections
.addServiceConnection(ServiceConnection.ofContainer("milvus", service, TESTCONTAINERS_CLASS_NAME, false)));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
package io.spring.start.site.extension.dependency.springai;

import io.spring.initializr.generator.condition.ConditionalOnRequestedDependency;
import io.spring.initializr.generator.project.ProjectDescription;
import io.spring.initializr.generator.project.ProjectGenerationConfiguration;
import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.start.site.container.ComposeFileCustomizer;
import io.spring.start.site.container.DockerServiceResolver;
import io.spring.start.site.container.ServiceConnections.ServiceConnection;
Expand All @@ -40,25 +38,16 @@ class SpringAiOllamaProjectGenerationConfiguration {

@Bean
@ConditionalOnRequestedDependency("testcontainers")
ServiceConnectionsCustomizer ollamaServiceConnectionsCustomizer(InitializrMetadata metadata,
ProjectDescription description, DockerServiceResolver serviceResolver) {
return (serviceConnections) -> {
if (SpringAiVersion.version1OrLater(metadata, description.getPlatformVersion())) {
serviceResolver.doWith("ollama", (service) -> serviceConnections
.addServiceConnection(ServiceConnection.ofContainer("ollama", service, TESTCONTAINERS_CLASS_NAME)));
}
};
ServiceConnectionsCustomizer ollamaServiceConnectionsCustomizer(DockerServiceResolver serviceResolver) {
return (serviceConnections) -> serviceResolver.doWith("ollama", (service) -> serviceConnections
.addServiceConnection(ServiceConnection.ofContainer("ollama", service, TESTCONTAINERS_CLASS_NAME, false)));
}

@Bean
@ConditionalOnRequestedDependency("docker-compose")
ComposeFileCustomizer ollamaComposeFileCustomizer(InitializrMetadata metadata, ProjectDescription description,
DockerServiceResolver serviceResolver) {
return (composeFile) -> {
if (SpringAiVersion.version1OrLater(metadata, description.getPlatformVersion())) {
serviceResolver.doWith("ollama", (service) -> composeFile.services().add("ollama", service));
}
};
ComposeFileCustomizer ollamaComposeFileCustomizer(DockerServiceResolver serviceResolver) {
return (composeFile) -> serviceResolver.doWith("ollama",
(service) -> composeFile.services().add("ollama", service));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
package io.spring.start.site.extension.dependency.springai;

import io.spring.initializr.generator.condition.ConditionalOnRequestedDependency;
import io.spring.initializr.generator.project.ProjectDescription;
import io.spring.initializr.generator.project.ProjectGenerationConfiguration;
import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.start.site.container.ComposeFileCustomizer;
import io.spring.start.site.container.DockerServiceResolver;
import io.spring.start.site.container.ServiceConnections.ServiceConnection;
Expand All @@ -40,25 +38,16 @@ class SpringAiQdrantProjectGenerationConfiguration {

@Bean
@ConditionalOnRequestedDependency("testcontainers")
ServiceConnectionsCustomizer qdrantServiceConnectionsCustomizer(InitializrMetadata metadata,
ProjectDescription description, DockerServiceResolver serviceResolver) {
return (serviceConnections) -> {
if (SpringAiVersion.version1OrLater(metadata, description.getPlatformVersion())) {
serviceResolver.doWith("qdrant", (service) -> serviceConnections
.addServiceConnection(ServiceConnection.ofContainer("qdrant", service, TESTCONTAINERS_CLASS_NAME)));
}
};
ServiceConnectionsCustomizer qdrantServiceConnectionsCustomizer(DockerServiceResolver serviceResolver) {
return (serviceConnections) -> serviceResolver.doWith("qdrant", (service) -> serviceConnections
.addServiceConnection(ServiceConnection.ofContainer("qdrant", service, TESTCONTAINERS_CLASS_NAME, false)));
}

@Bean
@ConditionalOnRequestedDependency("docker-compose")
ComposeFileCustomizer qdrantComposeFileCustomizer(InitializrMetadata metadata, ProjectDescription description,
DockerServiceResolver serviceResolver) {
return (composeFile) -> {
if (SpringAiVersion.version1OrLater(metadata, description.getPlatformVersion())) {
serviceResolver.doWith("qdrant", (service) -> composeFile.services().add("qdrant", service));
}
};
ComposeFileCustomizer qdrantComposeFileCustomizer(DockerServiceResolver serviceResolver) {
return (composeFile) -> serviceResolver.doWith("qdrant",
(service) -> composeFile.services().add("qdrant", service));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@
import io.spring.initializr.generator.buildsystem.Dependency;
import io.spring.initializr.generator.buildsystem.DependencyScope;
import io.spring.initializr.generator.condition.ConditionalOnRequestedDependency;
import io.spring.initializr.generator.project.ProjectDescription;
import io.spring.initializr.generator.project.ProjectGenerationConfiguration;
import io.spring.initializr.generator.spring.build.BuildCustomizer;
import io.spring.initializr.metadata.InitializrMetadata;

import org.springframework.context.annotation.Bean;

Expand All @@ -34,19 +32,15 @@
*/
@ProjectGenerationConfiguration
@ConditionalOnRequestedDependency("testcontainers")
@ConditionalOnRequestedSpringAiDependency
class SpringAiTestcontainersProjectGenerationConfiguration {

@Bean
BuildCustomizer<Build> springAiTestcontainersBuildCustomizer(InitializrMetadata metadata,
ProjectDescription description) {
return (build) -> {
if (SpringAiVersion.version1OrLater(metadata, description.getPlatformVersion())) {
build.dependencies()
.add("spring-ai-testcontainers",
Dependency.withCoordinates("org.springframework.ai", "spring-ai-spring-boot-testcontainers")
.scope(DependencyScope.TEST_COMPILE));
}
};
BuildCustomizer<Build> springAiTestcontainersBuildCustomizer() {
return (build) -> build.dependencies()
.add("spring-ai-testcontainers",
Dependency.withCoordinates("org.springframework.ai", "spring-ai-spring-boot-testcontainers")
.scope(DependencyScope.TEST_COMPILE));
}

}

This file was deleted.

Loading

0 comments on commit f114449

Please sign in to comment.