1616
1717package org .springframework .cloud .gateway .server .mvc ;
1818
19+ import java .time .Duration ;
20+
1921import org .junit .jupiter .api .Test ;
2022
23+ import org .springframework .boot .SpringBootConfiguration ;
2124import org .springframework .boot .autoconfigure .AutoConfigurations ;
25+ import org .springframework .boot .autoconfigure .EnableAutoConfiguration ;
2226import org .springframework .boot .autoconfigure .http .client .HttpClientAutoConfiguration ;
27+ import org .springframework .boot .autoconfigure .http .client .HttpClientProperties ;
2328import org .springframework .boot .autoconfigure .ssl .SslAutoConfiguration ;
2429import org .springframework .boot .autoconfigure .web .client .RestClientAutoConfiguration ;
2530import org .springframework .boot .autoconfigure .web .client .RestTemplateAutoConfiguration ;
31+ import org .springframework .boot .builder .SpringApplicationBuilder ;
2632import org .springframework .boot .test .context .runner .ApplicationContextRunner ;
27- import org .springframework .cloud .gateway .server .mvc .config .GatewayMvcProperties ;
2833import org .springframework .cloud .gateway .server .mvc .filter .FormFilter ;
2934import org .springframework .cloud .gateway .server .mvc .filter .ForwardedRequestHeadersFilter ;
3035import org .springframework .cloud .gateway .server .mvc .filter .RemoveContentLengthRequestHeadersFilter ;
3439import org .springframework .cloud .gateway .server .mvc .filter .TransferEncodingNormalizationRequestHeadersFilter ;
3540import org .springframework .cloud .gateway .server .mvc .filter .WeightCalculatorFilter ;
3641import org .springframework .cloud .gateway .server .mvc .filter .XForwardedRequestHeadersFilter ;
42+ import org .springframework .context .ConfigurableApplicationContext ;
43+ import org .springframework .http .client .JdkClientHttpRequestFactory ;
44+ import org .springframework .test .util .ReflectionTestUtils ;
3745
3846import static org .assertj .core .api .Assertions .assertThat ;
3947
4048public class GatewayServerMvcAutoConfigurationTests {
4149
4250 private static final String cert = """
43- -----BEGIN CERTIFICATE-----
44- MIIDqzCCApOgAwIBAgIIFMqbpqvipw0wDQYJKoZIhvcNAQELBQAwbDELMAkGA1UE
45- BhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVBhbG8gQWx0bzEP
46- MA0GA1UEChMGVk13YXJlMQ8wDQYDVQQLEwZTcHJpbmcxEjAQBgNVBAMTCWxvY2Fs
47- aG9zdDAgFw0yMzA1MDUxMTI2NThaGA8yMTIzMDQxMTExMjY1OFowbDELMAkGA1UE
48- BhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVBhbG8gQWx0bzEP
49- MA0GA1UEChMGVk13YXJlMQ8wDQYDVQQLEwZTcHJpbmcxEjAQBgNVBAMTCWxvY2Fs
50- aG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPwHWxoE3xjRmNdD
51- +m+e/aFlr5wEGQUdWSDD613OB1w7kqO/audEp3c6HxDB3GPcEL0amJwXgY6CQMYu
52- sythuZX/EZSc2HdilTBu/5T+mbdWe5JkKThpiA0RYeucQfKuB7zv4ypioa4wiR4D
53- nPsZXjg95OF8pCzYEssv8wT49v+M3ohWUgfF0FPlMFCSo0YVTuzB1mhDlWKq/jhQ
54- 11WpTmk/dQX+l6ts6bYIcJt4uItG+a68a4FutuSjZdTAE0f5SOYRBpGH96mjLwEP
55- fW8ZjzvKb9g4R2kiuoPxvCDs1Y/8V2yvKqLyn5Tx9x/DjFmOi0DRK/TgELvNceCb
56- UDJmhXMCAwEAAaNPME0wHQYDVR0OBBYEFMBIGU1nwix5RS3O5hGLLoMdR1+NMCwG
57- A1UdEQQlMCOCCWxvY2FsaG9zdIcQAAAAAAAAAAAAAAAAAAAAAYcEfwAAATANBgkq
58- hkiG9w0BAQsFAAOCAQEAhepfJgTFvqSccsT97XdAZfvB0noQx5NSynRV8NWmeOld
59- hHP6Fzj6xCxHSYvlUfmX8fVP9EOAuChgcbbuTIVJBu60rnDT21oOOnp8FvNonCV6
60- gJ89sCL7wZ77dw2RKIeUFjXXEV3QJhx2wCOVmLxnJspDoKFIEVjfLyiPXKxqe/6b
61- dG8zzWDZ6z+M2JNCtVoOGpljpHqMPCmbDktncv6H3dDTZ83bmLj1nbpOU587gAJ8
62- fl1PiUDyPRIl2cnOJd+wCHKsyym/FL7yzk0OSEZ81I92LpGd/0b2Ld3m/bpe+C4Z
63- ILzLXTnC6AhrLcDc9QN/EO+BiCL52n7EplNLtSn1LQ==
64- -----END CERTIFICATE-----
65- """ ;
51+ -----BEGIN CERTIFICATE-----
52+ MIIDqzCCApOgAwIBAgIIFMqbpqvipw0wDQYJKoZIhvcNAQELBQAwbDELMAkGA1UE
53+ BhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVBhbG8gQWx0bzEP
54+ MA0GA1UEChMGVk13YXJlMQ8wDQYDVQQLEwZTcHJpbmcxEjAQBgNVBAMTCWxvY2Fs
55+ aG9zdDAgFw0yMzA1MDUxMTI2NThaGA8yMTIzMDQxMTExMjY1OFowbDELMAkGA1UE
56+ BhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVBhbG8gQWx0bzEP
57+ MA0GA1UEChMGVk13YXJlMQ8wDQYDVQQLEwZTcHJpbmcxEjAQBgNVBAMTCWxvY2Fs
58+ aG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPwHWxoE3xjRmNdD
59+ +m+e/aFlr5wEGQUdWSDD613OB1w7kqO/audEp3c6HxDB3GPcEL0amJwXgY6CQMYu
60+ sythuZX/EZSc2HdilTBu/5T+mbdWe5JkKThpiA0RYeucQfKuB7zv4ypioa4wiR4D
61+ nPsZXjg95OF8pCzYEssv8wT49v+M3ohWUgfF0FPlMFCSo0YVTuzB1mhDlWKq/jhQ
62+ 11WpTmk/dQX+l6ts6bYIcJt4uItG+a68a4FutuSjZdTAE0f5SOYRBpGH96mjLwEP
63+ fW8ZjzvKb9g4R2kiuoPxvCDs1Y/8V2yvKqLyn5Tx9x/DjFmOi0DRK/TgELvNceCb
64+ UDJmhXMCAwEAAaNPME0wHQYDVR0OBBYEFMBIGU1nwix5RS3O5hGLLoMdR1+NMCwG
65+ A1UdEQQlMCOCCWxvY2FsaG9zdIcQAAAAAAAAAAAAAAAAAAAAAYcEfwAAATANBgkq
66+ hkiG9w0BAQsFAAOCAQEAhepfJgTFvqSccsT97XdAZfvB0noQx5NSynRV8NWmeOld
67+ hHP6Fzj6xCxHSYvlUfmX8fVP9EOAuChgcbbuTIVJBu60rnDT21oOOnp8FvNonCV6
68+ gJ89sCL7wZ77dw2RKIeUFjXXEV3QJhx2wCOVmLxnJspDoKFIEVjfLyiPXKxqe/6b
69+ dG8zzWDZ6z+M2JNCtVoOGpljpHqMPCmbDktncv6H3dDTZ83bmLj1nbpOU587gAJ8
70+ fl1PiUDyPRIl2cnOJd+wCHKsyym/FL7yzk0OSEZ81I92LpGd/0b2Ld3m/bpe+C4Z
71+ ILzLXTnC6AhrLcDc9QN/EO+BiCL52n7EplNLtSn1LQ==
72+ -----END CERTIFICATE-----
73+ """ ;
6674
6775 private static final String key = """
68- -----BEGIN PRIVATE KEY-----
69- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD8B1saBN8Y0ZjX
70- Q/pvnv2hZa+cBBkFHVkgw+tdzgdcO5Kjv2rnRKd3Oh8Qwdxj3BC9GpicF4GOgkDG
71- LrMrYbmV/xGUnNh3YpUwbv+U/pm3VnuSZCk4aYgNEWHrnEHyrge87+MqYqGuMIke
72- A5z7GV44PeThfKQs2BLLL/ME+Pb/jN6IVlIHxdBT5TBQkqNGFU7swdZoQ5Viqv44
73- UNdVqU5pP3UF/perbOm2CHCbeLiLRvmuvGuBbrbko2XUwBNH+UjmEQaRh/epoy8B
74- D31vGY87ym/YOEdpIrqD8bwg7NWP/Fdsryqi8p+U8fcfw4xZjotA0Sv04BC7zXHg
75- m1AyZoVzAgMBAAECggEAfEqiZqANaF+BqXQIb4Dw42ZTJzWsIyYYnPySOGZRoe5t
76- QJ03uwtULYv34xtANe1DQgd6SMyc46ugBzzjtprQ3ET5Jhn99U6kdcjf+dpf85dO
77- hOEppP0CkDNI39nleinSfh6uIOqYgt/D143/nqQhn8oCdSOzkbwT9KnWh1bC9T7I
78- vFjGfElvt1/xl88qYgrWgYLgXaencNGgiv/4/M0FNhiHEGsVC7SCu6kapC/WIQpE
79- 5IdV+HR+tiLoGZhXlhqorY7QC4xKC4wwafVSiFxqDOQAuK+SMD4TCEv0Aop+c+SE
80- YBigVTmgVeJkjK7IkTEhKkAEFmRF5/5w+bZD9FhTNQKBgQD+4fNG1ChSU8RdizZT
81- 5dPlDyAxpETSCEXFFVGtPPh2j93HDWn7XugNyjn5FylTH507QlabC+5wZqltdIjK
82- GRB5MIinQ9/nR2fuwGc9s+0BiSEwNOUB1MWm7wWL/JUIiKq6sTi6sJIfsYg79zco
83- qxl5WE94aoINx9Utq1cdWhwJTQKBgQD9IjPksd4Jprz8zMrGLzR8k1gqHyhv24qY
84- EJ7jiHKKAP6xllTUYwh1IBSL6w2j5lfZPpIkb4Jlk2KUoX6fN81pWkBC/fTBUSIB
85- EHM9bL51+yKEYUbGIy/gANuRbHXsWg3sjUsFTNPN4hGTFk3w2xChCyl/f5us8Lo8
86- Z633SNdpvwKBgQCGyDU9XzNzVZihXtx7wS0sE7OSjKtX5cf/UCbA1V0OVUWR3SYO
87- J0HPCQFfF0BjFHSwwYPKuaR9C8zMdLNhK5/qdh/NU7czNi9fsZ7moh7SkRFbzJzN
88- OxbKD9t/CzJEMQEXeF/nWTfsSpUgILqqZtAxuuFLbAcaAnJYlCKdAumQgQKBgQCK
89- mqjJh68pn7gJwGUjoYNe1xtGbSsqHI9F9ovZ0MPO1v6e5M7sQJHH+Fnnxzv/y8e8
90- d6tz8e73iX1IHymDKv35uuZHCGF1XOR+qrA/KQUc+vcKf21OXsP/JtkTRs1HLoRD
91- S5aRf2DWcfvniyYARSNU2xTM8GWgi2ueWbMDHUp+ZwKBgA/swC+K+Jg5DEWm6Sau
92- e6y+eC6S+SoXEKkI3wf7m9aKoZo0y+jh8Gas6gratlc181pSM8O3vZG0n19b493I
93- apCFomMLE56zEzvyzfpsNhFhk5MBMCn0LPyzX6MiynRlGyWIj0c99fbHI3pOMufP
94- WgmVLTZ8uDcSW1MbdUCwFSk5
95- -----END PRIVATE KEY-----
96- """ ;
76+ -----BEGIN PRIVATE KEY-----
77+ MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD8B1saBN8Y0ZjX
78+ Q/pvnv2hZa+cBBkFHVkgw+tdzgdcO5Kjv2rnRKd3Oh8Qwdxj3BC9GpicF4GOgkDG
79+ LrMrYbmV/xGUnNh3YpUwbv+U/pm3VnuSZCk4aYgNEWHrnEHyrge87+MqYqGuMIke
80+ A5z7GV44PeThfKQs2BLLL/ME+Pb/jN6IVlIHxdBT5TBQkqNGFU7swdZoQ5Viqv44
81+ UNdVqU5pP3UF/perbOm2CHCbeLiLRvmuvGuBbrbko2XUwBNH+UjmEQaRh/epoy8B
82+ D31vGY87ym/YOEdpIrqD8bwg7NWP/Fdsryqi8p+U8fcfw4xZjotA0Sv04BC7zXHg
83+ m1AyZoVzAgMBAAECggEAfEqiZqANaF+BqXQIb4Dw42ZTJzWsIyYYnPySOGZRoe5t
84+ QJ03uwtULYv34xtANe1DQgd6SMyc46ugBzzjtprQ3ET5Jhn99U6kdcjf+dpf85dO
85+ hOEppP0CkDNI39nleinSfh6uIOqYgt/D143/nqQhn8oCdSOzkbwT9KnWh1bC9T7I
86+ vFjGfElvt1/xl88qYgrWgYLgXaencNGgiv/4/M0FNhiHEGsVC7SCu6kapC/WIQpE
87+ 5IdV+HR+tiLoGZhXlhqorY7QC4xKC4wwafVSiFxqDOQAuK+SMD4TCEv0Aop+c+SE
88+ YBigVTmgVeJkjK7IkTEhKkAEFmRF5/5w+bZD9FhTNQKBgQD+4fNG1ChSU8RdizZT
89+ 5dPlDyAxpETSCEXFFVGtPPh2j93HDWn7XugNyjn5FylTH507QlabC+5wZqltdIjK
90+ GRB5MIinQ9/nR2fuwGc9s+0BiSEwNOUB1MWm7wWL/JUIiKq6sTi6sJIfsYg79zco
91+ qxl5WE94aoINx9Utq1cdWhwJTQKBgQD9IjPksd4Jprz8zMrGLzR8k1gqHyhv24qY
92+ EJ7jiHKKAP6xllTUYwh1IBSL6w2j5lfZPpIkb4Jlk2KUoX6fN81pWkBC/fTBUSIB
93+ EHM9bL51+yKEYUbGIy/gANuRbHXsWg3sjUsFTNPN4hGTFk3w2xChCyl/f5us8Lo8
94+ Z633SNdpvwKBgQCGyDU9XzNzVZihXtx7wS0sE7OSjKtX5cf/UCbA1V0OVUWR3SYO
95+ J0HPCQFfF0BjFHSwwYPKuaR9C8zMdLNhK5/qdh/NU7czNi9fsZ7moh7SkRFbzJzN
96+ OxbKD9t/CzJEMQEXeF/nWTfsSpUgILqqZtAxuuFLbAcaAnJYlCKdAumQgQKBgQCK
97+ mqjJh68pn7gJwGUjoYNe1xtGbSsqHI9F9ovZ0MPO1v6e5M7sQJHH+Fnnxzv/y8e8
98+ d6tz8e73iX1IHymDKv35uuZHCGF1XOR+qrA/KQUc+vcKf21OXsP/JtkTRs1HLoRD
99+ S5aRf2DWcfvniyYARSNU2xTM8GWgi2ueWbMDHUp+ZwKBgA/swC+K+Jg5DEWm6Sau
100+ e6y+eC6S+SoXEKkI3wf7m9aKoZo0y+jh8Gas6gratlc181pSM8O3vZG0n19b493I
101+ apCFomMLE56zEzvyzfpsNhFhk5MBMCn0LPyzX6MiynRlGyWIj0c99fbHI3pOMufP
102+ WgmVLTZ8uDcSW1MbdUCwFSk5
103+ -----END PRIVATE KEY-----
104+ """ ;
97105
98106 @ Test
99107 void filterEnabledPropertiesWork () {
100108 new ApplicationContextRunner ()
101109 .withConfiguration (AutoConfigurations .of (GatewayServerMvcAutoConfiguration .class ,
102- RestTemplateAutoConfiguration .class , RestClientAutoConfiguration .class , SslAutoConfiguration .class ))
110+ HttpClientAutoConfiguration .class , RestTemplateAutoConfiguration .class ,
111+ RestClientAutoConfiguration .class , SslAutoConfiguration .class ))
103112 .withPropertyValues ("spring.cloud.gateway.mvc.form-filter.enabled=false" ,
104113 "spring.cloud.gateway.mvc.forwarded-request-headers-filter.enabled=false" ,
105114 "spring.cloud.gateway.mvc.remove-content-length-request-headers-filter.enabled=false" ,
@@ -123,24 +132,55 @@ void filterEnabledPropertiesWork() {
123132 }
124133
125134 @ Test
126- void httpClientPropertiesWork () {
135+ void gatewayHttpClientPropertiesWork () {
136+ ConfigurableApplicationContext context = new SpringApplicationBuilder (TestConfig .class )
137+ .properties ("spring.main.web-application-type=none" ,
138+ "spring.cloud.gateway.mvc.http-client.connect-timeout=1s" ,
139+ "spring.cloud.gateway.mvc.http-client.connect-timeout=1s" ,
140+ "spring.cloud.gateway.mvc.http-client.read-timeout=2s" ,
141+ "spring.cloud.gateway.mvc.http-client.ssl-bundle=mybundle" ,
142+ "spring.cloud.gateway.mvc.http-client.type=autodetect" ,
143+ "spring.ssl.bundle.pem.mybundle.keystore.certificate=" + cert ,
144+ "spring.ssl.bundle.pem.mybundle.keystore.key=" + key )
145+ .run ();
146+ JdkClientHttpRequestFactory requestFactory = context .getBean (JdkClientHttpRequestFactory .class );
147+ HttpClientProperties properties = context .getBean (HttpClientProperties .class );
148+ assertThat (properties .getConnectTimeout ()).hasSeconds (1 );
149+ assertThat (properties .getReadTimeout ()).hasSeconds (2 );
150+ assertThat (properties .getSsl ().getBundle ()).isEqualTo ("mybundle" );
151+ assertThat (properties .getFactory ()).isNull ();
152+ Object readTimeout = ReflectionTestUtils .getField (requestFactory , "readTimeout" );
153+ assertThat (readTimeout ).isEqualTo (Duration .ofSeconds (2 ));
154+ }
155+
156+ @ Test
157+ void bootHttpClientPropertiesWork () {
127158 new ApplicationContextRunner ()
128- .withConfiguration (AutoConfigurations .of (GatewayServerMvcAutoConfiguration .class , HttpClientAutoConfiguration .class ,
129- RestTemplateAutoConfiguration .class , RestClientAutoConfiguration .class , SslAutoConfiguration .class ))
130- .withPropertyValues ("spring.cloud.gateway.mvc.http-client.connect-timeout=1s" ,
131- "spring.cloud.gateway.mvc.http-client.read-timeout=2s" ,
132- "spring.cloud.gateway.mvc.http-client.ssl-bundle=mybundle" ,
133- "spring.cloud.gateway.mvc.http-client.type=autodetect" ,
134- "spring.ssl.bundle.pem.mybundle.keystore.certificate=" + cert ,
135- "spring.ssl.bundle.pem.mybundle.keystore.key=" + key )
136- .run (context -> {
137- assertThat (context ).hasSingleBean (GatewayMvcProperties .class );
138- GatewayMvcProperties properties = context .getBean (GatewayMvcProperties .class );
139- GatewayMvcProperties .HttpClient httpClient = properties .getHttpClient ();
140- assertThat (httpClient .getConnectTimeout ()).hasSeconds (1 );
141- assertThat (httpClient .getReadTimeout ()).hasSeconds (2 );
142- assertThat (httpClient .getSslBundle ()).isEqualTo ("mybundle" );
143- assertThat (httpClient .getType ()).isEqualTo (GatewayMvcProperties .HttpClientType .AUTODETECT );
144- });
159+ .withConfiguration (AutoConfigurations .of (GatewayServerMvcAutoConfiguration .class ,
160+ HttpClientAutoConfiguration .class , RestTemplateAutoConfiguration .class ,
161+ RestClientAutoConfiguration .class , SslAutoConfiguration .class ))
162+ .withPropertyValues ("spring.http.client.connect-timeout=1s" , "spring.http.client.read-timeout=2s" ,
163+ "spring.http.client.ssl.bundle=mybundle" ,
164+ "spring.ssl.bundle.pem.mybundle.keystore.certificate=" + cert ,
165+ "spring.ssl.bundle.pem.mybundle.keystore.key=" + key )
166+ .run (context -> {
167+ assertThat (context ).hasSingleBean (JdkClientHttpRequestFactory .class )
168+ .hasSingleBean (HttpClientProperties .class );
169+ HttpClientProperties httpClient = context .getBean (HttpClientProperties .class );
170+ assertThat (httpClient .getConnectTimeout ()).hasSeconds (1 );
171+ assertThat (httpClient .getReadTimeout ()).hasSeconds (2 );
172+ assertThat (httpClient .getSsl ().getBundle ()).isEqualTo ("mybundle" );
173+ assertThat (httpClient .getFactory ()).isNull ();
174+ JdkClientHttpRequestFactory requestFactory = context .getBean (JdkClientHttpRequestFactory .class );
175+ Object readTimeout = ReflectionTestUtils .getField (requestFactory , "readTimeout" );
176+ assertThat (readTimeout ).isEqualTo (Duration .ofSeconds (2 ));
177+ });
178+ }
179+
180+ @ SpringBootConfiguration
181+ @ EnableAutoConfiguration
182+ static class TestConfig {
183+
145184 }
185+
146186}
0 commit comments