2222import de .codecentric .boot .admin .server .domain .values .InstanceId ;
2323import de .codecentric .boot .admin .server .domain .values .Registration ;
2424import de .codecentric .boot .admin .server .web .client .InstanceWebClient ;
25+ import io .netty .channel .ChannelOption ;
26+ import io .netty .handler .ssl .SslContextBuilder ;
27+ import io .netty .handler .ssl .util .InsecureTrustManagerFactory ;
28+ import io .netty .handler .timeout .ReadTimeoutHandler ;
29+ import reactor .netty .ConnectionObserver ;
30+ import reactor .netty .http .client .HttpClient ;
2531import reactor .test .StepVerifier ;
2632
33+ import java .util .concurrent .TimeUnit ;
2734import org .junit .Rule ;
2835import org .junit .Test ;
2936import org .springframework .boot .actuate .endpoint .http .ActuatorMediaType ;
3037import org .springframework .http .MediaType ;
31- import com . github . tomakehurst . wiremock . core . Options ;
38+ import org . springframework . http . client . reactive . ReactorClientHttpConnector ;
3239import com .github .tomakehurst .wiremock .http .Fault ;
3340import com .github .tomakehurst .wiremock .junit .WireMockRule ;
3441
3946import static com .github .tomakehurst .wiremock .client .WireMock .ok ;
4047import static com .github .tomakehurst .wiremock .client .WireMock .okJson ;
4148import static com .github .tomakehurst .wiremock .client .WireMock .urlPathEqualTo ;
49+ import static com .github .tomakehurst .wiremock .core .WireMockConfiguration .wireMockConfig ;
4250import static com .github .tomakehurst .wiremock .stubbing .Scenario .STARTED ;
4351import static java .util .Collections .singletonMap ;
4452
4553public class QueryIndexEndpointStrategyTest {
4654
4755 @ Rule
48- public WireMockRule wireMock = new WireMockRule (Options . DYNAMIC_PORT );
56+ public WireMockRule wireMock = new WireMockRule (wireMockConfig (). dynamicHttpsPort () );
4957
5058 private InstanceWebClient instanceWebClient = InstanceWebClient .builder ()
59+ .webClientCustomizer (wc -> wc .clientConnector (
60+ httpConnector ()))
5161 .retries (singletonMap (Endpoint .ACTUATOR_INDEX , 1 ))
5262 .build ();
5363
@@ -59,7 +69,16 @@ public void should_return_endpoints() {
5969 .managementUrl (this .wireMock .url ("/mgmt" ))
6070 .build ());
6171
62- String body = "{\" _links\" :{\" metrics-requiredMetricName\" :{\" templated\" :true,\" href\" :\" \\ /mgmt\\ /metrics\\ /{requiredMetricName}\" },\" self\" :{\" templated\" :false,\" href\" :\" \\ /mgmt\" },\" metrics\" :{\" templated\" :false,\" href\" :\" \\ /mgmt\\ /stats\" },\" info\" :{\" templated\" :false,\" href\" :\" \\ /mgmt\\ /info\" }}}" ;
72+ String host = "https://localhost:" + this .wireMock .httpsPort ();
73+ String body = "{\" _links\" :{\" metrics-requiredMetricName\" :{\" templated\" :true,\" href\" :\" " +
74+ host +
75+ "/mgmt/metrics/{requiredMetricName}\" },\" self\" :{\" templated\" :false,\" href\" :\" " +
76+ host +
77+ "/mgmt\" },\" metrics\" :{\" templated\" :false,\" href\" :\" " +
78+ host +
79+ "/mgmt/stats\" },\" info\" :{\" templated\" :false,\" href\" :\" " +
80+ host +
81+ "/mgmt/info\" }}}" ;
6382
6483 this .wireMock .stubFor (get ("/mgmt" ).willReturn (ok (body ).withHeader ("Content-Type" , ActuatorMediaType .V2_JSON )
6584 .withHeader ("Content-Length" ,
@@ -71,7 +90,43 @@ public void should_return_endpoints() {
7190 //when
7291 StepVerifier .create (strategy .detectEndpoints (instance ))
7392 //then
74- .expectNext (Endpoints .single ("metrics" , "/mgmt/stats" ).withEndpoint ("info" , "/mgmt/info" ))//
93+ .expectNext (Endpoints .single ("metrics" , host + "/mgmt/stats" )
94+ .withEndpoint ("info" , host + "/mgmt/info" ))//
95+ .verifyComplete ();
96+ }
97+
98+ @ Test
99+ public void should_return_endpoints_with_aligned_scheme () {
100+ //given
101+ Instance instance = Instance .create (InstanceId .of ("id" ))
102+ .register (Registration .create ("test" , this .wireMock .url ("/mgmt/health" ))
103+ .managementUrl (this .wireMock .url ("/mgmt" ))
104+ .build ());
105+
106+ String host = "http://localhost:" + this .wireMock .httpsPort ();
107+ String body = "{\" _links\" :{\" metrics-requiredMetricName\" :{\" templated\" :true,\" href\" :\" " +
108+ host +
109+ "/mgmt/metrics/{requiredMetricName}\" },\" self\" :{\" templated\" :false,\" href\" :\" " +
110+ host +
111+ "/mgmt\" },\" metrics\" :{\" templated\" :false,\" href\" :\" " +
112+ host +
113+ "/mgmt/stats\" },\" info\" :{\" templated\" :false,\" href\" :\" " +
114+ host +
115+ "/mgmt/info\" }}}" ;
116+
117+ this .wireMock .stubFor (get ("/mgmt" ).willReturn (ok (body ).withHeader ("Content-Type" , ActuatorMediaType .V2_JSON )
118+ .withHeader ("Content-Length" ,
119+ Integer .toString (body .length ())
120+ )));
121+
122+ QueryIndexEndpointStrategy strategy = new QueryIndexEndpointStrategy (this .instanceWebClient );
123+
124+ //when
125+ String secureHost = "https://localhost:" + this .wireMock .httpsPort ();
126+ StepVerifier .create (strategy .detectEndpoints (instance ))
127+ //then
128+ .expectNext (Endpoints .single ("metrics" , secureHost + "/mgmt/stats" )
129+ .withEndpoint ("info" , secureHost + "/mgmt/info" ))//
75130 .verifyComplete ();
76131 }
77132
@@ -180,7 +235,7 @@ public void should_retry() {
180235 .managementUrl (this .wireMock .url ("/mgmt" ))
181236 .build ());
182237
183- String body = "{\" _links\" :{\" metrics-requiredMetricName\" :{\" templated\" :true,\" href\" :\" \\ /mgmt\\ /metrics\\ /{requiredMetricName}\" },\" self\" :{\" templated\" :false,\" href\" :\" \\ /mgmt\" },\" metrics\" :{\" templated\" :false,\" href\" :\" \\ /mgmt\\ /stats\" },\" info\" :{\" templated\" :false,\" href\" :\" \\ /mgmt\\ /info\" }}}" ;
238+ String body = "{\" _links\" :{\" metrics-requiredMetricName\" :{\" templated\" :true,\" href\" :\" /mgmt/metrics/{requiredMetricName}\" },\" self\" :{\" templated\" :false,\" href\" :\" /mgmt\" },\" metrics\" :{\" templated\" :false,\" href\" :\" /mgmt/stats\" },\" info\" :{\" templated\" :false,\" href\" :\" /mgmt/info\" }}}" ;
184239
185240 this .wireMock .stubFor (get ("/mgmt" ).inScenario ("retry" )
186241 .whenScenarioStateIs (STARTED )
@@ -202,4 +257,24 @@ public void should_retry() {
202257 .expectNext (Endpoints .single ("metrics" , "/mgmt/stats" ).withEndpoint ("info" , "/mgmt/info" ))//
203258 .verifyComplete ();
204259 }
260+
261+ private ReactorClientHttpConnector httpConnector () {
262+ SslContextBuilder sslCtx = SslContextBuilder .forClient ().trustManager (InsecureTrustManagerFactory .INSTANCE );
263+
264+ HttpClient client = HttpClient .create ()
265+ .secure (ssl -> ssl .sslContext (sslCtx ))
266+ .compress (true )
267+ .tcpConfiguration (tcp -> tcp .bootstrap (bootstrap -> bootstrap .option (ChannelOption .CONNECT_TIMEOUT_MILLIS ,
268+ 2000
269+ ))
270+ .observe ((connection , newState ) -> {
271+ if (ConnectionObserver .State .CONNECTED .equals (
272+ newState )) {
273+ connection .addHandlerLast (new ReadTimeoutHandler (2000L ,
274+ TimeUnit .MILLISECONDS
275+ ));
276+ }
277+ }));
278+ return new ReactorClientHttpConnector (client );
279+ }
205280}
0 commit comments