Skip to content

Commit f106c14

Browse files
committed
Merge branch 'fix/lb-reconstruct-uri' of git://github.com/TYsewyn/spring-cloud-gateway into TYsewyn-fix/lb-reconstruct-uri
2 parents 858e706 + 09ba3ef commit f106c14

File tree

2 files changed

+100
-30
lines changed

2 files changed

+100
-30
lines changed

spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/LoadBalancerClientFilter.java

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,15 @@
2626
import org.springframework.cloud.gateway.support.NotFoundException;
2727
import org.springframework.core.Ordered;
2828
import org.springframework.web.server.ServerWebExchange;
29-
import org.springframework.web.util.UriComponentsBuilder;
3029

3130
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
3231
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.addOriginalRequestUrl;
33-
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.containsEncodedQuery;
3432

3533
import reactor.core.publisher.Mono;
3634

3735
/**
3836
* @author Spencer Gibb
37+
* @author Tim Ysewyn
3938
*/
4039
public class LoadBalancerClientFilter implements GlobalFilter, Ordered {
4140

@@ -70,15 +69,9 @@ public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
7069
throw new NotFoundException("Unable to find instance for " + url.getHost());
7170
}
7271

73-
/*URI uri = exchange.getRequest().getURI();
74-
URI requestUrl = loadBalancer.reconstructURI(instance, uri);*/
75-
boolean encoded = containsEncodedQuery(url);
76-
URI requestUrl = UriComponentsBuilder.fromUri(url)
77-
.scheme(instance.isSecure()? "https" : "http") //TODO: support websockets
78-
.host(instance.getHost())
79-
.port(instance.getPort())
80-
.build(encoded)
81-
.toUri();
72+
URI uri = exchange.getRequest().getURI();
73+
URI requestUrl = loadBalancer.reconstructURI(instance, uri);
74+
8275
log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
8376
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
8477
return chain.filter(exchange);

spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/LoadBalancerClientFilterTests.java

Lines changed: 96 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,124 @@
1-
/*
2-
* Copyright 2013-2017 the original author or authors.
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
15-
*
16-
*/
17-
181
package org.springframework.cloud.gateway.filter;
192

203
import java.net.URI;
214
import java.util.Collections;
5+
import java.util.LinkedHashSet;
226

7+
import org.junit.Before;
238
import org.junit.Test;
9+
import org.junit.runner.RunWith;
2410
import org.mockito.ArgumentCaptor;
11+
import org.mockito.InjectMocks;
12+
import org.mockito.Mock;
13+
import org.mockito.junit.MockitoJUnitRunner;
2514
import org.springframework.cloud.client.DefaultServiceInstance;
15+
import org.springframework.cloud.client.ServiceInstance;
2616
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
17+
import org.springframework.cloud.gateway.support.NotFoundException;
2718
import org.springframework.http.HttpMethod;
2819
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
2920
import org.springframework.mock.web.server.MockServerWebExchange;
3021
import org.springframework.web.server.ServerWebExchange;
3122
import org.springframework.web.util.UriComponentsBuilder;
3223

3324
import static org.assertj.core.api.Assertions.assertThat;
25+
import static org.mockito.ArgumentMatchers.any;
26+
import static org.mockito.ArgumentMatchers.eq;
3427
import static org.mockito.Mockito.mock;
28+
import static org.mockito.Mockito.verify;
29+
import static org.mockito.Mockito.verifyNoMoreInteractions;
30+
import static org.mockito.Mockito.verifyZeroInteractions;
3531
import static org.mockito.Mockito.when;
32+
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR;
3633
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
3734

3835
import reactor.core.publisher.Mono;
3936

4037
/**
4138
* @author Spencer Gibb
39+
* @author Tim Ysewyn
4240
*/
41+
@RunWith(MockitoJUnitRunner.class)
4342
public class LoadBalancerClientFilterTests {
4443

44+
private ServerWebExchange exchange;
45+
46+
@Mock
47+
private GatewayFilterChain chain;
48+
49+
@Mock
50+
private LoadBalancerClient loadBalancerClient;
51+
52+
@InjectMocks
53+
private LoadBalancerClientFilter loadBalancerClientFilter;
54+
55+
@Before
56+
public void setup() {
57+
exchange = MockServerWebExchange.from(MockServerHttpRequest.get("loadbalancerclient.org").build());
58+
}
59+
60+
@Test
61+
public void shouldNotFilterWhenGatewayRequestUrlIsMissing() {
62+
loadBalancerClientFilter.filter(exchange, chain);
63+
64+
verify(chain).filter(exchange);
65+
verifyNoMoreInteractions(chain);
66+
verifyZeroInteractions(loadBalancerClient);
67+
}
68+
69+
@Test
70+
public void shouldNotFilterWhenGatewayRequestUrlSchemeIsNotLb() {
71+
URI uri = UriComponentsBuilder.fromUriString("http://myservice").build().toUri();
72+
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, uri);
73+
74+
loadBalancerClientFilter.filter(exchange, chain);
75+
76+
verify(chain).filter(exchange);
77+
verifyNoMoreInteractions(chain);
78+
verifyZeroInteractions(loadBalancerClient);
79+
}
80+
81+
@Test(expected = NotFoundException.class)
82+
public void shouldThrowExceptionWhenNoServiceInstanceIsFound() {
83+
URI uri = UriComponentsBuilder.fromUriString("lb://myservice").build().toUri();
84+
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, uri);
85+
86+
loadBalancerClientFilter.filter(exchange, chain);
87+
}
88+
89+
@Test
90+
public void shouldFilter() {
91+
URI url = UriComponentsBuilder.fromUriString("lb://myservice").build().toUri();
92+
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, url);
93+
94+
ServiceInstance serviceInstance = new DefaultServiceInstance("myservice", "localhost", 8080, true);
95+
when(loadBalancerClient.choose("myservice")).thenReturn(serviceInstance);
96+
97+
URI requestUrl = UriComponentsBuilder.fromUriString("https://localhost:8080").build().toUri();
98+
when(loadBalancerClient.reconstructURI(any(ServiceInstance.class), any(URI.class))).thenReturn(requestUrl);
99+
100+
loadBalancerClientFilter.filter(exchange, chain);
101+
102+
assertThat((LinkedHashSet<URI>)exchange.getAttribute(GATEWAY_ORIGINAL_REQUEST_URL_ATTR)).contains(url);
103+
104+
verify(loadBalancerClient).choose("myservice");
105+
106+
ArgumentCaptor<URI> urlArgumentCaptor = ArgumentCaptor.forClass(URI.class);
107+
verify(loadBalancerClient).reconstructURI(eq(serviceInstance), urlArgumentCaptor.capture());
108+
109+
URI uri = urlArgumentCaptor.getValue();
110+
assertThat(uri).isNotNull();
111+
assertThat(uri.toString()).isEqualTo("loadbalancerclient.org");
112+
113+
verifyNoMoreInteractions(loadBalancerClient);
114+
115+
assertThat((URI)exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)).isEqualTo(requestUrl);
116+
117+
verify(chain).filter(exchange);
118+
verifyNoMoreInteractions(chain);
119+
}
120+
121+
45122
@Test
46123
public void happyPath() {
47124
MockServerHttpRequest request = MockServerHttpRequest
@@ -126,9 +203,9 @@ private ServerWebExchange testFilter(MockServerHttpRequest request, URI uri) {
126203

127204
LoadBalancerClient loadBalancerClient = mock(LoadBalancerClient.class);
128205
when(loadBalancerClient.choose("service1")).
129-
thenReturn(new DefaultServiceInstance("service1", "service1-host1", 8081,
206+
thenReturn(new DefaultServiceInstance("service1", "service1-host1", 8081,
130207
false, Collections.emptyMap()));
131-
208+
132209
LoadBalancerClientFilter filter = new LoadBalancerClientFilter(loadBalancerClient);
133210
filter.filter(exchange, filterChain);
134211

0 commit comments

Comments
 (0)