Skip to content

Commit abefc0f

Browse files
committed
chore: adding tests to mock out calls to config endpoin
1 parent fc3725f commit abefc0f

File tree

9 files changed

+308
-47
lines changed

9 files changed

+308
-47
lines changed

java-cfenv-boot-tanzu-genai/src/main/java/io/pivotal/cfenv/boot/genai/CfGenaiProcessor.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,33 @@
1+
/*
2+
* Copyright 2025 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+
*/
116
package io.pivotal.cfenv.boot.genai;
217

18+
import java.util.Map;
19+
320
import io.pivotal.cfenv.core.CfCredentials;
421
import io.pivotal.cfenv.core.CfService;
522
import io.pivotal.cfenv.spring.boot.CfEnvProcessor;
623
import io.pivotal.cfenv.spring.boot.CfEnvProcessorProperties;
724

8-
import java.util.Map;
9-
25+
/**
26+
* Retrieve GenAI on Tanzu Platform properties from {@link CfCredentials} and
27+
* set {@literal genai.locator.*} Boot properties.
28+
*
29+
* @author Gareth Evans
30+
**/
1031
public class CfGenaiProcessor implements CfEnvProcessor {
1132

1233
@Override

java-cfenv-boot-tanzu-genai/src/main/java/io/pivotal/cfenv/boot/genai/DefaultGenAILocator.java renamed to java-cfenv-boot-tanzu-genai/src/main/java/io/pivotal/cfenv/boot/genai/DefaultGenaiLocator.java

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,29 @@
1+
/*
2+
* Copyright 2025 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+
*/
116
package io.pivotal.cfenv.boot.genai;
217

18+
import java.util.List;
19+
import java.util.Map;
20+
import java.util.function.Predicate;
21+
322
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
423
import com.fasterxml.jackson.annotation.JsonProperty;
524
import org.slf4j.Logger;
625
import org.slf4j.LoggerFactory;
26+
727
import org.springframework.ai.chat.model.ChatModel;
828
import org.springframework.ai.document.MetadataMode;
929
import org.springframework.ai.embedding.EmbeddingModel;
@@ -14,20 +34,22 @@
1434
import org.springframework.ai.openai.api.OpenAiApi;
1535
import org.springframework.web.client.RestClient;
1636

17-
import java.util.AbstractMap;
18-
import java.util.List;
19-
import java.util.Map;
20-
import java.util.function.Predicate;
21-
22-
public class DefaultGenAILocator implements GenAILocator {
37+
/**
38+
* Locates available models and mcp servers from ai-servers config endpoint
39+
*
40+
* @author Gareth Evans
41+
**/
42+
public class DefaultGenaiLocator implements GenaiLocator {
2343

24-
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultGenAILocator.class);
44+
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultGenaiLocator.class);
2545

2646
private final String configUrl;
2747
private final String apiKey;
2848
private final String apiBase;
49+
private final RestClient.Builder builder;
2950

30-
public DefaultGenAILocator(String configUrl, String apiKey, String apiBase) {
51+
public DefaultGenaiLocator(RestClient.Builder builder, String configUrl, String apiKey, String apiBase) {
52+
this.builder = builder;
3153
this.configUrl = configUrl;
3254
this.apiKey = apiKey;
3355
this.apiBase = apiBase;
@@ -67,7 +89,7 @@ public ChatModel getChatModelByName(String name) {
6789
return models.stream()
6890
.filter(filterModelConnectivityOnCapability("CHAT"))
6991
.filter(c -> c.name().equals(name))
70-
.map(DefaultGenAILocator::createChatModel)
92+
.map(DefaultGenaiLocator::createChatModel)
7193
.findFirst()
7294
.orElseThrow(
7395
() -> new RuntimeException("Unable to find chat model with name '" + name + "'"));
@@ -80,7 +102,7 @@ public List<ChatModel> getChatModelsByLabels(Map<String, String> labels) {
80102
return models.stream()
81103
.filter(filterModelConnectivityOnCapability("CHAT"))
82104
.filter(filterModelConnectivityOnLabels(labels))
83-
.map(DefaultGenAILocator::createChatModel)
105+
.map(DefaultGenaiLocator::createChatModel)
84106
.toList();
85107
}
86108

@@ -90,7 +112,7 @@ public ChatModel getFirstAvailableChatModel() {
90112

91113
return models.stream()
92114
.filter(filterModelConnectivityOnCapability("CHAT"))
93-
.map(DefaultGenAILocator::createChatModel)
115+
.map(DefaultGenaiLocator::createChatModel)
94116
.findFirst()
95117
.orElseThrow(() -> new RuntimeException("Unable to find first chat model"));
96118
}
@@ -102,7 +124,7 @@ public ChatModel getFirstAvailableChatModelByLabels(Map<String, String> labels)
102124
return models.stream()
103125
.filter(filterModelConnectivityOnCapability("CHAT"))
104126
.filter(filterModelConnectivityOnLabels(labels))
105-
.map(DefaultGenAILocator::createChatModel)
127+
.map(DefaultGenaiLocator::createChatModel)
106128
.findFirst()
107129
.orElseThrow(() -> new RuntimeException("Unable to find first chat model"));
108130
}
@@ -114,7 +136,7 @@ public List<ChatModel> getToolModelsByLabels(Map<String, String> labels) {
114136
return models.stream()
115137
.filter(filterModelConnectivityOnCapability("TOOLS"))
116138
.filter(filterModelConnectivityOnLabels(labels))
117-
.map(DefaultGenAILocator::createChatModel)
139+
.map(DefaultGenaiLocator::createChatModel)
118140
.toList();
119141
}
120142

@@ -124,7 +146,7 @@ public ChatModel getFirstAvailableToolModel() {
124146

125147
return models.stream()
126148
.filter(filterModelConnectivityOnCapability("TOOLS"))
127-
.map(DefaultGenAILocator::createChatModel)
149+
.map(DefaultGenaiLocator::createChatModel)
128150
.findFirst()
129151
.orElseThrow(() -> new RuntimeException("Unable to find first tool model"));
130152
}
@@ -136,7 +158,7 @@ public ChatModel getFirstAvailableToolModelByLabels(Map<String, String> labels)
136158
return models.stream()
137159
.filter(filterModelConnectivityOnCapability("TOOLS"))
138160
.filter(filterModelConnectivityOnLabels(labels))
139-
.map(DefaultGenAILocator::createChatModel)
161+
.map(DefaultGenaiLocator::createChatModel)
140162
.findFirst()
141163
.orElseThrow(() -> new RuntimeException("Unable to find first tool model"));
142164
}
@@ -156,7 +178,7 @@ public EmbeddingModel getEmbeddingModelByName(String name) {
156178
return models.stream()
157179
.filter(filterModelConnectivityOnCapability("EMBEDDING"))
158180
.filter(c -> c.name().equals(name))
159-
.map(DefaultGenAILocator::createEmbeddingModel)
181+
.map(DefaultGenaiLocator::createEmbeddingModel)
160182
.findFirst()
161183
.orElseThrow(
162184
() -> new RuntimeException("Unable to find embedding model with name '" + name + "'"));
@@ -169,7 +191,7 @@ public List<EmbeddingModel> getEmbeddingModelsByLabels(Map<String, String> label
169191
return models.stream()
170192
.filter(filterModelConnectivityOnCapability("EMBEDDING"))
171193
.filter(filterModelConnectivityOnLabels(labels))
172-
.map(DefaultGenAILocator::createEmbeddingModel)
194+
.map(DefaultGenaiLocator::createEmbeddingModel)
173195
.toList();
174196
}
175197

@@ -179,7 +201,7 @@ public EmbeddingModel getFirstAvailableEmbeddingModel() {
179201

180202
return models.stream()
181203
.filter(filterModelConnectivityOnCapability("EMBEDDING"))
182-
.map(DefaultGenAILocator::createEmbeddingModel)
204+
.map(DefaultGenaiLocator::createEmbeddingModel)
183205
.findFirst()
184206
.orElseThrow(() -> new RuntimeException("Unable to find first embedding model"));
185207
}
@@ -191,7 +213,7 @@ public EmbeddingModel getFirstAvailableEmbeddingModelByLabels(Map<String, String
191213
return models.stream()
192214
.filter(filterModelConnectivityOnCapability("EMBEDDING"))
193215
.filter(filterModelConnectivityOnLabels(labels))
194-
.map(DefaultGenAILocator::createEmbeddingModel)
216+
.map(DefaultGenaiLocator::createEmbeddingModel)
195217
.findFirst()
196218
.orElseThrow(() -> new RuntimeException("Unable to find first embedding model"));
197219
}
@@ -231,7 +253,7 @@ private List<McpConnectivity> getAllMcpConnectivityDetails() {
231253
}
232254

233255
private ConfigEndpoint getEndpointConfig() {
234-
RestClient client = RestClient.builder().build();
256+
RestClient client = builder.build();
235257
return client
236258
.get()
237259
.uri(configUrl)

java-cfenv-boot-tanzu-genai/src/main/java/io/pivotal/cfenv/boot/genai/GenAILocatorAutoConfiguration.java

Lines changed: 0 additions & 18 deletions
This file was deleted.

java-cfenv-boot-tanzu-genai/src/main/java/io/pivotal/cfenv/boot/genai/GenAILocator.java renamed to java-cfenv-boot-tanzu-genai/src/main/java/io/pivotal/cfenv/boot/genai/GenaiLocator.java

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,34 @@
1+
/*
2+
* Copyright 2025 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+
*/
116
package io.pivotal.cfenv.boot.genai;
217

18+
import java.util.List;
19+
import java.util.Map;
20+
321
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
22+
423
import org.springframework.ai.chat.model.ChatModel;
524
import org.springframework.ai.embedding.EmbeddingModel;
625

7-
import java.util.List;
8-
import java.util.Map;
9-
10-
public interface GenAILocator {
26+
/**
27+
* Locates available models and mcp servers from ai-servers config endpoint
28+
*
29+
* @author Gareth Evans
30+
**/
31+
public interface GenaiLocator {
1132

1233
List<String> getModelNames();
1334

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2025 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+
package io.pivotal.cfenv.boot.genai;
17+
18+
import org.springframework.beans.factory.annotation.Value;
19+
import org.springframework.boot.autoconfigure.AutoConfiguration;
20+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
21+
import org.springframework.context.annotation.Bean;
22+
import org.springframework.web.client.RestClient;
23+
24+
/**
25+
* Auto configuration for the genai locator.
26+
*
27+
* @author Gareth Evans
28+
**/
29+
@AutoConfiguration
30+
@ConditionalOnProperty("genai.locator.config-url")
31+
public class GenaiLocatorAutoConfiguration {
32+
33+
@Bean
34+
public GenaiLocator genaiLocator(
35+
RestClient.Builder builder,
36+
@Value("genai.locator.config-url") String configUrl,
37+
@Value("genai.locator.api-key") String apiKey,
38+
@Value("genai.locator.api-base") String apiBase
39+
) {
40+
return new DefaultGenaiLocator(builder, configUrl, apiKey, apiBase);
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
io.pivotal.cfenv.boot.genai.GenAILocatorAutoConfiguration
1+
io.pivotal.cfenv.boot.genai.GenaiLocatorAutoConfiguration
22

java-cfenv-boot-tanzu-genai/src/test/java/io/pivotal/cfenv/boot/genai/BootIntegrationTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019 the original author or authors.
2+
* Copyright 2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

java-cfenv-boot-tanzu-genai/src/test/java/io/pivotal/cfenv/boot/genai/GenAICfEnvProcessorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2024 the original author or authors.
2+
* Copyright 2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

0 commit comments

Comments
 (0)