4
4
5
5
import java .io .InputStream ;
6
6
import java .net .URI ;
7
- import java .net .URISyntaxException ;
8
7
import java .nio .file .Files ;
9
8
import java .nio .file .Path ;
9
+ import java .time .Duration ;
10
10
import java .util .ArrayList ;
11
11
import java .util .List ;
12
12
import java .util .Map ;
20
20
21
21
import io .quarkus .runtime .ResettableSystemProperties ;
22
22
import io .quarkus .runtime .util .ClassPathUtils ;
23
+ import io .quarkus .spring .cloud .config .client .runtime .eureka .DiscoveryService ;
24
+ import io .quarkus .spring .cloud .config .client .runtime .eureka .EurekaClient ;
25
+ import io .quarkus .spring .cloud .config .client .runtime .eureka .EurekaResponseMapper ;
26
+ import io .quarkus .spring .cloud .config .client .runtime .eureka .RandomEurekaInstanceSelector ;
27
+ import io .quarkus .spring .cloud .config .client .runtime .util .UrlUtility ;
23
28
import io .smallrye .mutiny .Uni ;
24
29
import io .vertx .core .VertxOptions ;
25
30
import io .vertx .core .net .JksOptions ;
@@ -44,18 +49,41 @@ public class VertxSpringCloudConfigGateway implements SpringCloudConfigClientGat
44
49
private final SpringCloudConfigClientConfig config ;
45
50
private final Vertx vertx ;
46
51
private final WebClient webClient ;
47
- private final URI baseURI ;
52
+ private final ConfigServerBaseUrlProvider configServerBaseUrlProvider ;
48
53
49
54
public VertxSpringCloudConfigGateway (SpringCloudConfigClientConfig config ) {
50
55
this .config = config ;
51
- try {
52
- this .baseURI = determineBaseUri (config );
53
- } catch (URISyntaxException e ) {
54
- throw new IllegalArgumentException ("Value: '" + config .url ()
55
- + "' of property 'quarkus.spring-cloud-config.url' is invalid" , e );
56
- }
57
56
this .vertx = createVertxInstance ();
58
57
this .webClient = createHttpClient (vertx , config );
58
+ this .configServerBaseUrlProvider = createConfigServerProvider (config );
59
+ }
60
+
61
+ private ConfigServerBaseUrlProvider createConfigServerProvider (SpringCloudConfigClientConfig config ) {
62
+ if (!config .discovery ().isPresent () || (!config .discovery ().get ().enabled ())) {
63
+ return new DirectConfigServerBaseUrlProvider (config );
64
+ }
65
+ DiscoveryService discoveryService = createDiscoveryService (config .discovery ().get ());
66
+ return new DiscoveryConfigServerBaseUrlProvider (discoveryService , config );
67
+ }
68
+
69
+ private DiscoveryService createDiscoveryService (SpringCloudConfigClientConfig .DiscoveryConfig config ) {
70
+ EurekaClient eurekaClient = createEurekaClient (config .eurekaConfig ().get ());
71
+ return new DiscoveryService (eurekaClient );
72
+ }
73
+
74
+ private EurekaClient createEurekaClient (SpringCloudConfigClientConfig .DiscoveryConfig .EurekaConfig config ) {
75
+ if (config == null ) {
76
+ throw new IllegalArgumentException ("Eureka configuration is required" );
77
+ }
78
+ Duration fetchInterval = config .registryFetchIntervalSeconds ();
79
+ EurekaResponseMapper responseMapper = new EurekaResponseMapper ();
80
+ RandomEurekaInstanceSelector instanceSelector = new RandomEurekaInstanceSelector ();
81
+
82
+ return new EurekaClient (
83
+ webClient ,
84
+ fetchInterval ,
85
+ responseMapper ,
86
+ instanceSelector );
59
87
}
60
88
61
89
private Vertx createVertxInstance () {
@@ -156,54 +184,43 @@ private static byte[] allBytes(InputStream inputStream) throws Exception {
156
184
return inputStream .readAllBytes ();
157
185
}
158
186
159
- private URI determineBaseUri (SpringCloudConfigClientConfig springCloudConfigClientConfig ) throws URISyntaxException {
160
- String url = springCloudConfigClientConfig .url ();
161
- if (null == url || url .isEmpty ()) {
162
- throw new IllegalArgumentException (
163
- "The 'quarkus.spring-cloud-config.url' property cannot be empty" );
164
- }
165
- if (url .endsWith ("/" )) {
166
- return new URI (url .substring (0 , url .length () - 1 ));
167
- }
168
- return new URI (url );
169
- }
170
-
171
- private String finalURI (String applicationName , String profile ) {
187
+ private ConfigServerUrl toConfigServerUrl (String applicationName , String profile ) {
188
+ URI baseURI = configServerBaseUrlProvider .get ();
172
189
String path = baseURI .getPath ();
173
- List <String > finalPathSegments = new ArrayList <String >();
190
+ List <String > finalPathSegments = new ArrayList <>();
174
191
finalPathSegments .add (path );
175
192
finalPathSegments .add (applicationName );
176
193
finalPathSegments .add (profile );
177
194
if (config .label ().isPresent ()) {
178
195
finalPathSegments .add (config .label ().get ());
179
196
}
180
- return String .join ("/" , finalPathSegments );
197
+ return new ConfigServerUrl (baseURI , UrlUtility .getPort (baseURI ), baseURI .getHost (),
198
+ String .join ("/" , finalPathSegments ));
181
199
}
182
200
183
201
@ Override
184
202
public Uni <Response > exchange (String applicationName , String profile ) {
185
- final String requestURI = finalURI (applicationName , profile );
186
- String finalURI = getFinalURI (applicationName , profile );
203
+ final ConfigServerUrl requestURI = toConfigServerUrl (applicationName , profile );
187
204
HttpRequest <Buffer > request = webClient
188
- .get (getPort ( baseURI ), baseURI . getHost (), requestURI )
189
- .ssl (isHttps (baseURI ))
205
+ .get (requestURI . port ( ), requestURI . host (), requestURI . completeURLString () )
206
+ .ssl (UrlUtility . isHttps (requestURI . baseURI () ))
190
207
.putHeader ("Accept" , "application/json" );
191
208
if (config .usernameAndPasswordSet ()) {
192
209
request .basicAuthentication (config .username ().get (), config .password ().get ());
193
210
}
194
211
for (Map .Entry <String , String > entry : config .headers ().entrySet ()) {
195
212
request .putHeader (entry .getKey (), entry .getValue ());
196
213
}
197
- log .debug ("Attempting to read configuration from '" + finalURI + "'." );
214
+ log .debug ("Attempting to read configuration from '" + requestURI . completeURLString () + "'." );
198
215
return request .send ().map (r -> {
199
216
log .debug ("Received HTTP response code '" + r .statusCode () + "'" );
200
217
if (r .statusCode () != 200 ) {
201
218
throw new RuntimeException ("Got unexpected HTTP response code " + r .statusCode ()
202
- + " from " + finalURI );
219
+ + " from " + requestURI . completeURLString () );
203
220
} else {
204
221
String bodyAsString = r .bodyAsString ();
205
222
if (bodyAsString .isEmpty ()) {
206
- throw new RuntimeException ("Got empty HTTP response body " + finalURI );
223
+ throw new RuntimeException ("Got empty HTTP response body " + requestURI . completeURLString () );
207
224
}
208
225
try {
209
226
log .debug ("Attempting to deserialize response" );
@@ -215,22 +232,6 @@ public Uni<Response> exchange(String applicationName, String profile) {
215
232
});
216
233
}
217
234
218
- private boolean isHttps (URI uri ) {
219
- return uri .getScheme ().contains ("https" );
220
- }
221
-
222
- private int getPort (URI uri ) {
223
- return uri .getPort () != -1 ? uri .getPort () : (isHttps (uri ) ? 443 : 80 );
224
- }
225
-
226
- private String getFinalURI (String applicationName , String profile ) {
227
- String finalURI = baseURI .toString () + "/" + applicationName + "/" + profile ;
228
- if (config .label ().isPresent ()) {
229
- finalURI += "/" + config .label ().get ();
230
- }
231
- return finalURI ;
232
- }
233
-
234
235
@ Override
235
236
public void close () {
236
237
this .webClient .close ();
0 commit comments