1616
1717package org .springframework .integration .http ;
1818
19+ import java .net .URI ;
1920import java .time .Instant ;
2021import java .time .ZoneId ;
2122import java .time .ZonedDateTime ;
2223import java .time .format .DateTimeFormatter ;
2324import java .util .Calendar ;
2425import java .util .Locale ;
26+ import java .util .concurrent .atomic .AtomicReference ;
27+ import java .util .function .Consumer ;
28+ import java .util .function .Function ;
2529
2630import org .junit .jupiter .api .Test ;
27- import org .mockito .Mockito ;
2831
2932import org .springframework .beans .DirectFieldAccessor ;
30- import org .springframework .beans .PropertyAccessor ;
3133import org .springframework .beans .factory .annotation .Autowired ;
3234import org .springframework .beans .factory .annotation .Qualifier ;
3335import org .springframework .http .HttpEntity ;
3436import org .springframework .http .HttpHeaders ;
35- import org .springframework .http .HttpMethod ;
3637import org .springframework .http .HttpStatus ;
3738import org .springframework .http .ResponseEntity ;
3839import org .springframework .integration .http .outbound .HttpRequestExecutingMessageHandler ;
4546import org .springframework .test .context .junit .jupiter .SpringJUnitConfig ;
4647import org .springframework .test .web .servlet .request .MockMvcRequestBuilders ;
4748import org .springframework .util .MultiValueMap ;
48- import org .springframework .web .client .RestTemplate ;
49+ import org .springframework .web .client .RestClient ;
4950import org .springframework .web .context .request .RequestAttributes ;
5051import org .springframework .web .context .request .RequestContextHolder ;
5152import org .springframework .web .context .request .ServletRequestAttributes ;
5455import org .springframework .web .servlet .mvc .HttpRequestHandlerAdapter ;
5556
5657import static org .assertj .core .api .Assertions .assertThat ;
58+ import static org .mockito .ArgumentMatchers .any ;
59+ import static org .mockito .ArgumentMatchers .anyMap ;
60+ import static org .mockito .ArgumentMatchers .anyString ;
61+ import static org .mockito .Mockito .mock ;
62+ import static org .mockito .Mockito .when ;
5763
5864/**
5965 * @author Artem Bilan
6066 * @author Gary Russell
6167 * @author Arun Sethumadhavan
68+ * @author Burak Kalayci
6269 *
6370 * @since 3.0
6471 */
@@ -115,31 +122,19 @@ public void testHttpProxyScenario() throws Exception {
115122
116123 MockHttpServletResponse response = new MockHttpServletResponse ();
117124
118- RestTemplate template = Mockito .spy (new RestTemplate ());
119-
120125 final String contentDispositionValue = "attachment; filename=\" test.txt\" " ;
121126
122- Mockito .doAnswer (invocation -> {
123- String uri = invocation .getArgument (0 );
124- assertThat (uri ).isEqualTo ("http://testServer/test?foo=bar&FOO=BAR" );
125- HttpEntity <?> httpEntity = (HttpEntity <?>) invocation .getArguments ()[2 ];
126- HttpHeaders httpHeaders = httpEntity .getHeaders ();
127- assertThat (httpHeaders .getIfModifiedSince ()).isEqualTo (ifModifiedSince );
128- assertThat (httpHeaders .getFirst ("If-Unmodified-Since" )).isEqualTo (ifUnmodifiedSinceValue );
129- assertThat (httpHeaders .getFirst ("Connection" )).isEqualTo ("Keep-Alive" );
130-
131- HttpHeaders responseHeaders = HttpHeaders .copyOf (httpHeaders );
132- responseHeaders .set ("Connection" , "close" );
133- responseHeaders .set ("Content-Disposition" , contentDispositionValue );
134- return new ResponseEntity <>(responseHeaders , HttpStatus .OK );
135- }).when (template )
136- .exchange (Mockito .anyString (), Mockito .any (HttpMethod .class ),
137- Mockito .any (HttpEntity .class ), Mockito .<Class <?>>any (), Mockito .anyMap ());
138-
139- PropertyAccessor dfa = new DirectFieldAccessor (this .handler );
140- dfa .setPropertyValue ("localRestClientBuilder" , null );
141- dfa .setPropertyValue ("restClient" , null );
142- dfa .setPropertyValue ("restTemplate" , template );
127+ injectRestClient (this .handler , httpEntity -> {
128+ HttpHeaders httpHeaders = httpEntity .getHeaders ();
129+ assertThat (httpHeaders .getIfModifiedSince ()).isEqualTo (ifModifiedSince );
130+ assertThat (httpHeaders .getFirst ("If-Unmodified-Since" )).isEqualTo (ifUnmodifiedSinceValue );
131+ assertThat (httpHeaders .getFirst ("Connection" )).isEqualTo ("Keep-Alive" );
132+
133+ HttpHeaders responseHeaders = HttpHeaders .copyOf (httpHeaders );
134+ responseHeaders .set ("Connection" , "close" );
135+ responseHeaders .set ("Content-Disposition" , contentDispositionValue );
136+ return new ResponseEntity <>(responseHeaders , HttpStatus .OK );
137+ }, uri -> assertThat (uri ).isEqualTo ("http://testServer/test?foo=bar&FOO=BAR" ));
143138
144139 RequestAttributes attributes = new ServletRequestAttributes (request );
145140 RequestContextHolder .setRequestAttributes (attributes );
@@ -176,33 +171,21 @@ public void testHttpMultipartProxyScenario() throws Exception {
176171
177172 MockHttpServletResponse response = new MockHttpServletResponse ();
178173
179- RestTemplate template = Mockito .spy (new RestTemplate ());
180- Mockito .doAnswer (invocation -> {
181- String uri = invocation .getArgument (0 );
182- assertThat (uri ).isEqualTo ("http://testServer/testmp" );
183- HttpEntity <?> httpEntity = (HttpEntity <?>) invocation .getArguments ()[2 ];
184- HttpHeaders httpHeaders = httpEntity .getHeaders ();
185- assertThat (httpHeaders .getFirst ("Connection" )).isEqualTo ("Keep-Alive" );
186- assertThat (httpHeaders .getContentType ().toString ())
187- .isEqualTo ("multipart/form-data;boundary=----WebKitFormBoundarywABD2xqC1FLBijlQ" );
188-
189- HttpEntity <?> entity = (HttpEntity <?>) invocation .getArguments ()[2 ];
190- assertThat (entity .getBody ()).isInstanceOf (MultiValueMap .class );
191- assertThat (((MultiValueMap <String , ?>) entity .getBody ()).getFirst ("foo" ))
192- .isEqualTo ("foo" .getBytes ());
193-
194- HttpHeaders responseHeaders = HttpHeaders .copyOf (httpHeaders );
195- responseHeaders .set ("Connection" , "close" );
196- responseHeaders .set ("Content-Type" , "text/plain" );
197- return new ResponseEntity <>(responseHeaders , HttpStatus .OK );
198- }).when (template )
199- .exchange (Mockito .anyString (), Mockito .any (HttpMethod .class ),
200- Mockito .any (HttpEntity .class ), Mockito .<Class <?>>any (), Mockito .anyMap ());
201-
202- PropertyAccessor dfa = new DirectFieldAccessor (this .handlermp );
203- dfa .setPropertyValue ("localRestClientBuilder" , null );
204- dfa .setPropertyValue ("restClient" , null );
205- dfa .setPropertyValue ("restTemplate" , template );
174+ injectRestClient (this .handlermp , httpEntity -> {
175+ HttpHeaders httpHeaders = httpEntity .getHeaders ();
176+ assertThat (httpHeaders .getFirst ("Connection" )).isEqualTo ("Keep-Alive" );
177+ assertThat (httpHeaders .getContentType ().toString ())
178+ .isEqualTo ("multipart/form-data;boundary=----WebKitFormBoundarywABD2xqC1FLBijlQ" );
179+
180+ assertThat (httpEntity .getBody ()).isInstanceOf (MultiValueMap .class );
181+ assertThat (((MultiValueMap <String , ?>) httpEntity .getBody ()).getFirst ("foo" ))
182+ .isEqualTo ("foo" .getBytes ());
183+
184+ HttpHeaders responseHeaders = HttpHeaders .copyOf (httpHeaders );
185+ responseHeaders .set ("Connection" , "close" );
186+ responseHeaders .set ("Content-Type" , "text/plain" );
187+ return new ResponseEntity <>(responseHeaders , HttpStatus .OK );
188+ }, uri -> assertThat (uri ).isEqualTo ("http://testServer/testmp" ));
206189
207190 RequestAttributes attributes = new ServletRequestAttributes (request );
208191 RequestContextHolder .setRequestAttributes (attributes );
@@ -215,4 +198,44 @@ public void testHttpMultipartProxyScenario() throws Exception {
215198 RequestContextHolder .resetRequestAttributes ();
216199 }
217200
201+ @ SuppressWarnings ("unchecked" )
202+ private static void injectRestClient (HttpRequestExecutingMessageHandler handler ,
203+ Function <HttpEntity <?>, ResponseEntity <?>> exchange ,
204+ Consumer <String > uriAsserter ) {
205+
206+ RestClient restClient = mock (RestClient .class );
207+ RestClient .RequestBodyUriSpec spec = mock (RestClient .RequestBodyUriSpec .class );
208+ RestClient .ResponseSpec responseSpec = mock (RestClient .ResponseSpec .class );
209+ HttpHeaders headers = new HttpHeaders ();
210+ AtomicReference <Object > body = new AtomicReference <>();
211+ AtomicReference <ResponseEntity <?>> response = new AtomicReference <>();
212+
213+ when (restClient .method (any ())).thenReturn (spec );
214+ when (spec .uri (any (URI .class ))).thenAnswer (invocation -> {
215+ uriAsserter .accept (invocation .getArgument (0 ).toString ());
216+ return spec ;
217+ });
218+ when (spec .uri (anyString (), anyMap ())).thenAnswer (invocation -> {
219+ uriAsserter .accept (invocation .getArgument (0 ));
220+ return spec ;
221+ });
222+ when (spec .headers (any ())).thenAnswer (invocation -> {
223+ Consumer <HttpHeaders > headerConsumer = invocation .getArgument (0 );
224+ headerConsumer .accept (headers );
225+ return spec ;
226+ });
227+ when (spec .body (any (Object .class ))).thenAnswer (invocation -> {
228+ body .set (invocation .getArgument (0 ));
229+ return spec ;
230+ });
231+ when (spec .retrieve ()).thenAnswer (invocation -> {
232+ response .set (exchange .apply (new HttpEntity <>(body .get (), headers )));
233+ return responseSpec ;
234+ });
235+ when (responseSpec .toEntity (any (Class .class ))).thenAnswer (invocation -> response .get ());
236+ when (responseSpec .toBodilessEntity ()).thenAnswer (invocation -> response .get ());
237+
238+ new DirectFieldAccessor (handler ).setPropertyValue ("restClient" , restClient );
239+ }
240+
218241}
0 commit comments