Skip to content

Commit a7f311d

Browse files
committed
Fix mutating global RestClient and WebClient builders
Since the builders for HTTP clients are mutable and shared, they should only be configured with globally applicable settings. The current use leaks specific details into other usages and affects newly instantiated clients. This PR applies the clone() method right before mutation happens as it probably is the strategy that avoids multiple unnecessary copies. Signed-off-by: Dariusz Jędrzejczyk <[email protected]>
1 parent 10ff11d commit a7f311d

File tree

7 files changed

+20
-8
lines changed

7 files changed

+20
-8
lines changed

models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/api/AnthropicApi.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,14 @@ private AnthropicApi(String baseUrl, String completionsPath, String anthropicApi
119119

120120
this.completionsPath = completionsPath;
121121

122-
this.restClient = restClientBuilder.baseUrl(baseUrl)
122+
this.restClient = restClientBuilder.clone()
123+
.baseUrl(baseUrl)
123124
.defaultHeaders(jsonContentHeaders)
124125
.defaultStatusHandler(responseErrorHandler)
125126
.build();
126127

127-
this.webClient = webClientBuilder.baseUrl(baseUrl)
128+
this.webClient = webClientBuilder.clone()
129+
.baseUrl(baseUrl)
128130
.defaultHeaders(jsonContentHeaders)
129131
.defaultStatusHandler(HttpStatusCode::isError,
130132
resp -> resp.bodyToMono(String.class)

models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/api/MiniMaxApi.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public MiniMaxApi(String baseUrl, String miniMaxToken, RestClient.Builder restCl
115115
.defaultStatusHandler(responseErrorHandler)
116116
.build();
117117

118-
this.webClient = WebClient.builder()
118+
this.webClient = WebClient.builder() // FIXME: use a bean instead
119119
.baseUrl(baseUrl)
120120
.defaultHeaders(authHeaders)
121121
.build();

models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiApi.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,11 @@ public MistralAiApi(String baseUrl, String mistralAiApiKey, RestClient.Builder r
112112
.defaultStatusHandler(responseErrorHandler)
113113
.build();
114114

115-
this.webClient = WebClient.builder().baseUrl(baseUrl).defaultHeaders(jsonContentHeaders).build();
115+
this.webClient = WebClient.builder().baseUrl(baseUrl).defaultHeaders(jsonContentHeaders).build(); // FIXME:
116+
// use
117+
// a
118+
// bean
119+
// instead
116120
}
117121

118122
/**

models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaApi.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,13 @@ private OllamaApi(String baseUrl, RestClient.Builder restClientBuilder, WebClien
8080
};
8181

8282
this.restClient = restClientBuilder.baseUrl(baseUrl)
83+
.clone()
8384
.defaultHeaders(defaultHeaders)
8485
.defaultStatusHandler(responseErrorHandler)
8586
.build();
8687

8788
this.webClient = webClientBuilder
89+
.clone()
8890
.baseUrl(baseUrl)
8991
.defaultHeaders(defaultHeaders)
9092
.build();

models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,15 @@ public OpenAiApi(String baseUrl, ApiKey apiKey, MultiValueMap<String, String> he
115115
h.setContentType(MediaType.APPLICATION_JSON);
116116
h.addAll(headers);
117117
};
118-
this.restClient = restClientBuilder.baseUrl(baseUrl)
118+
this.restClient = restClientBuilder
119+
.clone()
120+
.baseUrl(baseUrl)
119121
.defaultHeaders(finalHeaders)
120122
.defaultStatusHandler(responseErrorHandler)
121123
.build();
122124

123125
this.webClient = webClientBuilder
126+
.clone()
124127
.baseUrl(baseUrl)
125128
.defaultHeaders(finalHeaders)
126129
.build(); // @formatter:on

models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,13 @@ public OpenAiAudioApi(String baseUrl, ApiKey apiKey, MultiValueMap<String, Strin
7777
// h.setContentType(MediaType.APPLICATION_JSON);
7878
};
7979

80-
this.restClient = restClientBuilder.baseUrl(baseUrl)
80+
this.restClient = restClientBuilder.clone()
81+
.baseUrl(baseUrl)
8182
.defaultHeaders(authHeaders)
8283
.defaultStatusHandler(responseErrorHandler)
8384
.build();
8485

85-
this.webClient = webClientBuilder.baseUrl(baseUrl).defaultHeaders(authHeaders).build();
86+
this.webClient = webClientBuilder.clone().baseUrl(baseUrl).defaultHeaders(authHeaders).build();
8687
}
8788

8889
public static Builder builder() {

models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiApi.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public ZhiPuAiApi(String baseUrl, String zhiPuAiToken, RestClient.Builder restCl
116116
.defaultStatusHandler(responseErrorHandler)
117117
.build();
118118

119-
this.webClient = WebClient.builder()
119+
this.webClient = WebClient.builder() // FIXME: use a builder instead
120120
.baseUrl(baseUrl)
121121
.defaultHeaders(authHeaders)
122122
.build();

0 commit comments

Comments
 (0)