Introduce support for GenAI for Tanzu Platform bindings.
Currently this is a PreProvisionedService with a secret derived from the TPCF service key. Signed-off-by: Stuart Charlton <stuart.charlton@broadcom.com>
This commit is contained in:
committed by
Soby Chacko
parent
72011baf50
commit
86cfe6158a
@@ -0,0 +1,47 @@
|
||||
package org.springframework.ai.bindings;
|
||||
|
||||
import org.springframework.cloud.bindings.Binding;
|
||||
import org.springframework.cloud.bindings.Bindings;
|
||||
import org.springframework.cloud.bindings.boot.BindingsPropertiesProcessor;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An implementation of {@link BindingsPropertiesProcessor} that detects {@link Binding}s
|
||||
* of type: {@value TYPE}.
|
||||
*
|
||||
* @author Stuart Charlton
|
||||
*/
|
||||
public class TanzuBindingsPropertiesProcessor implements BindingsPropertiesProcessor {
|
||||
|
||||
/**
|
||||
* The {@link Binding} type that this processor is interested in: {@value}.
|
||||
**/
|
||||
public static final String TYPE = "genai";
|
||||
|
||||
@Override
|
||||
public void process(Environment environment, Bindings bindings, Map<String, Object> properties) {
|
||||
if (!BindingsValidator.isTypeEnabled(environment, TYPE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bindings.filterBindings(TYPE).forEach(binding -> {
|
||||
if (binding.getSecret().get("model-capabilities") != null) {
|
||||
String[] capabilities = binding.getSecret().get("model-capabilities").trim().split("\\s*,\\s*");
|
||||
if (Arrays.stream(capabilities).anyMatch("chat"::equals)) {
|
||||
properties.put("spring.ai.openai.chat.api-key", binding.getSecret().get("api-key"));
|
||||
properties.put("spring.ai.openai.chat.base-url", binding.getSecret().get("uri"));
|
||||
properties.put("spring.ai.openai.chat.options.model", binding.getSecret().get("model-name"));
|
||||
}
|
||||
if (Arrays.stream(capabilities).anyMatch("embedding"::equals)) {
|
||||
properties.put("spring.ai.openai.embedding.api-key", binding.getSecret().get("api-key"));
|
||||
properties.put("spring.ai.openai.embedding.base-url", binding.getSecret().get("uri"));
|
||||
properties.put("spring.ai.openai.embedding.options.model", binding.getSecret().get("model-name"));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,4 +3,5 @@ org.springframework.cloud.bindings.boot.BindingsPropertiesProcessor=\
|
||||
org.springframework.ai.bindings.ChromaBindingsPropertiesProcessor,\
|
||||
org.springframework.ai.bindings.OllamaBindingsPropertiesProcessor,\
|
||||
org.springframework.ai.bindings.OpenAiBindingsPropertiesProcessor,\
|
||||
org.springframework.ai.bindings.TanzuBindingsPropertiesProcessor,\
|
||||
org.springframework.ai.bindings.WeaviateBindingsPropertiesProcessor
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package org.springframework.ai.bindings;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.cloud.bindings.Binding;
|
||||
import org.springframework.cloud.bindings.Bindings;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.ai.bindings.BindingsValidator.CONFIG_PATH;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link TanzuBindingsPropertiesProcessor}.
|
||||
*
|
||||
* @author Stuart Charlton
|
||||
*/
|
||||
class TanzuBindingsPropertiesProcessorTests {
|
||||
|
||||
private final Bindings bindings = new Bindings(new Binding("test-name", Paths.get("test-path"),
|
||||
// @formatter:off
|
||||
Map.of(
|
||||
Binding.TYPE, TanzuBindingsPropertiesProcessor.TYPE,
|
||||
"api-key", "demo",
|
||||
"uri", "https://my.openai.example.net",
|
||||
"model-name", "llava1.6",
|
||||
"model-capabilities", " chat , vision "
|
||||
)),
|
||||
new Binding("test-name2", Paths.get("test-path2"),
|
||||
Map.of(
|
||||
Binding.TYPE, TanzuBindingsPropertiesProcessor.TYPE,
|
||||
"api-key", "demo2",
|
||||
"uri", "https://my.openai2.example.net",
|
||||
"model-name", "text-embed-large",
|
||||
"model-capabilities", "embedding")));
|
||||
// @formatter:on
|
||||
|
||||
private final Bindings bindingsMissingModelCapabilities = new Bindings(
|
||||
new Binding("test-name", Paths.get("test-path"),
|
||||
// @formatter:off
|
||||
Map.of(
|
||||
Binding.TYPE, TanzuBindingsPropertiesProcessor.TYPE,
|
||||
"api-key", "demo",
|
||||
"uri", "https://my.openai.example.net"
|
||||
)));
|
||||
// @formatter:on
|
||||
|
||||
private final MockEnvironment environment = new MockEnvironment();
|
||||
|
||||
private final Map<String, Object> properties = new HashMap<>();
|
||||
|
||||
@Test
|
||||
void propertiesAreContributed() {
|
||||
new TanzuBindingsPropertiesProcessor().process(environment, bindings, properties);
|
||||
assertThat(properties).containsEntry("spring.ai.openai.chat.api-key", "demo");
|
||||
assertThat(properties).containsEntry("spring.ai.openai.chat.base-url", "https://my.openai.example.net");
|
||||
assertThat(properties).containsEntry("spring.ai.openai.chat.options.model", "llava1.6");
|
||||
assertThat(properties).containsEntry("spring.ai.openai.embedding.api-key", "demo2");
|
||||
assertThat(properties).containsEntry("spring.ai.openai.embedding.base-url", "https://my.openai2.example.net");
|
||||
assertThat(properties).containsEntry("spring.ai.openai.embedding.options.model", "text-embed-large");
|
||||
}
|
||||
|
||||
@Test
|
||||
void propertiesAreMissingModelCapabilities() {
|
||||
new TanzuBindingsPropertiesProcessor().process(environment, bindingsMissingModelCapabilities, properties);
|
||||
assertThat(properties).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenDisabledThenPropertiesAreNotContributed() {
|
||||
environment.setProperty("%s.genai.enabled".formatted(CONFIG_PATH), "false");
|
||||
|
||||
new TanzuBindingsPropertiesProcessor().process(environment, bindings, properties);
|
||||
assertThat(properties).isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user