16
16
17
17
package org .springframework .boot .autoconfigure .data .elasticsearch ;
18
18
19
+ import java .net .URI ;
20
+ import java .time .Duration ;
21
+ import java .util .List ;
22
+ import java .util .Set ;
23
+ import java .util .stream .Collectors ;
24
+
19
25
import reactor .netty .http .client .HttpClient ;
20
26
21
27
import org .springframework .boot .autoconfigure .EnableAutoConfiguration ;
22
28
import org .springframework .boot .autoconfigure .condition .ConditionalOnClass ;
23
29
import org .springframework .boot .autoconfigure .condition .ConditionalOnMissingBean ;
30
+ import org .springframework .boot .autoconfigure .elasticsearch .ElasticsearchProperties ;
24
31
import org .springframework .boot .context .properties .EnableConfigurationProperties ;
25
32
import org .springframework .boot .context .properties .PropertyMapper ;
26
33
import org .springframework .context .annotation .Bean ;
29
36
import org .springframework .data .elasticsearch .client .reactive .ReactiveElasticsearchClient ;
30
37
import org .springframework .data .elasticsearch .client .reactive .ReactiveRestClients ;
31
38
import org .springframework .data .elasticsearch .client .reactive .ReactiveRestClients .WebClientConfigurationCallback ;
39
+ import org .springframework .util .Assert ;
32
40
import org .springframework .util .unit .DataSize ;
33
41
import org .springframework .web .reactive .function .client .ExchangeStrategies ;
34
42
import org .springframework .web .reactive .function .client .WebClient ;
40
48
* @author Brian Clozel
41
49
* @since 2.2.0
42
50
*/
51
+ @ SuppressWarnings ("deprecation" )
43
52
@ Configuration (proxyBeanMethods = false )
44
53
@ ConditionalOnClass ({ ReactiveRestClients .class , WebClient .class , HttpClient .class })
45
- @ EnableConfigurationProperties (ReactiveElasticsearchRestClientProperties .class )
54
+ @ EnableConfigurationProperties ({ ElasticsearchProperties .class , ReactiveElasticsearchRestClientProperties .class ,
55
+ DeprecatedReactiveElasticsearchRestClientProperties .class })
46
56
public class ReactiveElasticsearchRestClientAutoConfiguration {
47
57
58
+ private final ConsolidatedProperties properties ;
59
+
60
+ ReactiveElasticsearchRestClientAutoConfiguration (ElasticsearchProperties properties ,
61
+ ReactiveElasticsearchRestClientProperties restClientProperties ,
62
+ DeprecatedReactiveElasticsearchRestClientProperties reactiveProperties ) {
63
+ this .properties = new ConsolidatedProperties (properties , restClientProperties , reactiveProperties );
64
+ }
65
+
48
66
@ Bean
49
67
@ ConditionalOnMissingBean
50
- public ClientConfiguration clientConfiguration (ReactiveElasticsearchRestClientProperties properties ) {
68
+ public ClientConfiguration clientConfiguration () {
51
69
ClientConfiguration .MaybeSecureClientConfigurationBuilder builder = ClientConfiguration .builder ()
52
- .connectedTo (properties .getEndpoints ().toArray (new String [0 ]));
70
+ .connectedTo (this . properties .getEndpoints ().toArray (new String [0 ]));
53
71
PropertyMapper map = PropertyMapper .get ().alwaysApplyingWhenNonNull ();
54
- map .from (properties .isUseSsl ()).whenTrue ().toCall (builder ::usingSsl );
55
- map .from (properties .getUsername ()). whenHasText ( )
56
- .to ((username ) -> builder .withBasicAuth (username , properties .getPassword ()));
57
- map .from (properties .getConnectionTimeout ()).to (builder ::withConnectTimeout );
58
- map .from (properties .getSocketTimeout ()).to (builder ::withSocketTimeout );
59
- configureExchangeStrategies (map , builder , properties );
72
+ map .from (this . properties .isUseSsl ()).whenTrue ().toCall (builder ::usingSsl );
73
+ map .from (this . properties .getCredentials () )
74
+ .to ((credentials ) -> builder .withBasicAuth (credentials . getUsername (), credentials .getPassword ()));
75
+ map .from (this . properties .getConnectionTimeout ()).to (builder ::withConnectTimeout );
76
+ map .from (this . properties .getSocketTimeout ()).to (builder ::withSocketTimeout );
77
+ configureExchangeStrategies (map , builder );
60
78
return builder .build ();
61
79
}
62
80
63
81
private void configureExchangeStrategies (PropertyMapper map ,
64
- ClientConfiguration .TerminalClientConfigurationBuilder builder ,
65
- ReactiveElasticsearchRestClientProperties properties ) {
66
- map .from (properties .getMaxInMemorySize ()).asInt (DataSize ::toBytes ).to ((maxInMemorySize ) -> {
82
+ ClientConfiguration .TerminalClientConfigurationBuilder builder ) {
83
+ map .from (this .properties .getMaxInMemorySize ()).asInt (DataSize ::toBytes ).to ((maxInMemorySize ) -> {
67
84
builder .withClientConfigurer (WebClientConfigurationCallback .from ((webClient ) -> {
68
85
ExchangeStrategies exchangeStrategies = ExchangeStrategies .builder ()
69
86
.codecs ((configurer ) -> configurer .defaultCodecs ().maxInMemorySize (maxInMemorySize )).build ();
@@ -78,4 +95,166 @@ public ReactiveElasticsearchClient reactiveElasticsearchClient(ClientConfigurati
78
95
return ReactiveRestClients .create (clientConfiguration );
79
96
}
80
97
98
+ private static final class ConsolidatedProperties {
99
+
100
+ private final ElasticsearchProperties properties ;
101
+
102
+ private final ReactiveElasticsearchRestClientProperties restClientProperties ;
103
+
104
+ private final DeprecatedReactiveElasticsearchRestClientProperties deprecatedProperties ;
105
+
106
+ private final List <URI > uris ;
107
+
108
+ private ConsolidatedProperties (ElasticsearchProperties properties ,
109
+ ReactiveElasticsearchRestClientProperties restClientProperties ,
110
+ DeprecatedReactiveElasticsearchRestClientProperties deprecatedreactiveProperties ) {
111
+ this .properties = properties ;
112
+ this .restClientProperties = restClientProperties ;
113
+ this .deprecatedProperties = deprecatedreactiveProperties ;
114
+ this .uris = properties .getUris ().stream ().map ((s ) -> s .startsWith ("http" ) ? s : "http://" + s )
115
+ .map (URI ::create ).collect (Collectors .toList ());
116
+ }
117
+
118
+ private List <String > getEndpoints () {
119
+ if (this .deprecatedProperties .isCustomized ()) {
120
+ return this .deprecatedProperties .getEndpoints ();
121
+ }
122
+ return this .uris .stream ().map ((uri ) -> uri .getHost () + ":" + uri .getPort ()).collect (Collectors .toList ());
123
+ }
124
+
125
+ private Credentials getCredentials () {
126
+ if (this .deprecatedProperties .isCustomized ()) {
127
+ return Credentials .from (this .deprecatedProperties );
128
+ }
129
+ Credentials propertyCredentials = Credentials .from (this .properties );
130
+ Credentials uriCredentials = Credentials .from (this .properties .getUris ());
131
+ if (uriCredentials == null ) {
132
+ return propertyCredentials ;
133
+ }
134
+ if (propertyCredentials != null && !uriCredentials .equals (propertyCredentials )) {
135
+ throw new IllegalArgumentException (
136
+ "Credentials from URI user info do not match those from spring.elasticsearch.username and "
137
+ + "spring.elasticsearch.password" );
138
+ }
139
+ return uriCredentials ;
140
+
141
+ }
142
+
143
+ private Duration getConnectionTimeout () {
144
+ return this .deprecatedProperties .isCustomized () ? this .deprecatedProperties .getConnectionTimeout ()
145
+ : this .properties .getConnectionTimeout ();
146
+ }
147
+
148
+ private Duration getSocketTimeout () {
149
+ return this .deprecatedProperties .isCustomized () ? this .deprecatedProperties .getSocketTimeout ()
150
+ : this .properties .getSocketTimeout ();
151
+ }
152
+
153
+ private boolean isUseSsl () {
154
+ if (this .deprecatedProperties .isCustomized ()) {
155
+ return this .deprecatedProperties .isUseSsl ();
156
+ }
157
+ Set <String > schemes = this .uris .stream ().map ((uri ) -> uri .getScheme ()).collect (Collectors .toSet ());
158
+ Assert .isTrue (schemes .size () == 1 , () -> "Configured Elasticsearch URIs have varying schemes" );
159
+ return schemes .iterator ().next ().equals ("https" );
160
+ }
161
+
162
+ private DataSize getMaxInMemorySize () {
163
+ return this .deprecatedProperties .isCustomized () ? this .deprecatedProperties .getMaxInMemorySize ()
164
+ : this .restClientProperties .getMaxInMemorySize ();
165
+ }
166
+
167
+ private static final class Credentials {
168
+
169
+ private final String username ;
170
+
171
+ private final String password ;
172
+
173
+ private Credentials (String username , String password ) {
174
+ this .username = username ;
175
+ this .password = password ;
176
+ }
177
+
178
+ private String getUsername () {
179
+ return this .username ;
180
+ }
181
+
182
+ private String getPassword () {
183
+ return this .password ;
184
+ }
185
+
186
+ private static Credentials from (List <String > uris ) {
187
+ Set <String > userInfos = uris .stream ().map (URI ::create ).map ((uri ) -> uri .getUserInfo ())
188
+ .collect (Collectors .toSet ());
189
+ Assert .isTrue (userInfos .size () == 1 , () -> "Configured Elasticsearch URIs have varying user infos" );
190
+ String userInfo = userInfos .iterator ().next ();
191
+ if (userInfo != null ) {
192
+ String [] parts = userInfo .split (":" );
193
+ return new Credentials (parts [0 ], (parts .length == 2 ) ? parts [1 ] : "" );
194
+ }
195
+ return null ;
196
+ }
197
+
198
+ private static Credentials from (ElasticsearchProperties properties ) {
199
+ String username = properties .getUsername ();
200
+ String password = properties .getPassword ();
201
+ if (username == null && password == null ) {
202
+ return null ;
203
+ }
204
+ return new Credentials (username , password );
205
+ }
206
+
207
+ private static Credentials from (DeprecatedReactiveElasticsearchRestClientProperties properties ) {
208
+ String username = properties .getUsername ();
209
+ String password = properties .getPassword ();
210
+ if (username == null && password == null ) {
211
+ return null ;
212
+ }
213
+ return new Credentials (username , password );
214
+ }
215
+
216
+ @ Override
217
+ public boolean equals (Object obj ) {
218
+ if (this == obj ) {
219
+ return true ;
220
+ }
221
+ if (obj == null ) {
222
+ return false ;
223
+ }
224
+ if (getClass () != obj .getClass ()) {
225
+ return false ;
226
+ }
227
+ Credentials other = (Credentials ) obj ;
228
+ if (this .password == null ) {
229
+ if (other .password != null ) {
230
+ return false ;
231
+ }
232
+ }
233
+ else if (!this .password .equals (other .password )) {
234
+ return false ;
235
+ }
236
+ if (this .username == null ) {
237
+ if (other .username != null ) {
238
+ return false ;
239
+ }
240
+ }
241
+ else if (!this .username .equals (other .username )) {
242
+ return false ;
243
+ }
244
+ return true ;
245
+ }
246
+
247
+ @ Override
248
+ public int hashCode () {
249
+ final int prime = 31 ;
250
+ int result = 1 ;
251
+ result = prime * result + ((this .password == null ) ? 0 : this .password .hashCode ());
252
+ result = prime * result + ((this .username == null ) ? 0 : this .username .hashCode ());
253
+ return result ;
254
+ }
255
+
256
+ }
257
+
258
+ }
259
+
81
260
}
0 commit comments