use of org.springframework.cloud.client.loadbalancer.Response in project hummer-framework by hummer-team.
the class GlobalLoadBalancerFilter method filter.
/**
* Process the Web request and (optionally) delegate to the next {@code WebFilter}
* through the given {@link GatewayFilterChain}.
*
* @param exchange the current server exchange
* @param chain provides a way to delegate to the next filter
* @return {@code Mono<Void>} to indicate when request processing is complete
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI url = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
if (url == null) {
return chain.filter(exchange);
}
String schemePrefix = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR);
if (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix)) {
return chain.filter(exchange);
}
ServerWebExchangeUtils.addOriginalRequestUrl(exchange, url);
if (log.isTraceEnabled()) {
log.trace(ReactiveLoadBalancerClientFilter.class.getSimpleName() + " url before: " + url);
}
return choose(exchange).doOnNext((response) -> {
if (!response.hasServer()) {
throw NotFoundException.create(false, "Unable to find instance for " + url.getHost());
} else {
URI uri = exchange.getRequest().getURI();
String overrideScheme = null;
if (schemePrefix != null) {
overrideScheme = url.getScheme();
}
DelegatingServiceInstance serviceInstance = new DelegatingServiceInstance(response.getServer(), overrideScheme);
URI requestUrl = LoadBalancerUriTools.reconstructURI(serviceInstance, uri);
if (log.isTraceEnabled()) {
log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
}
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, requestUrl);
}
}).then(chain.filter(exchange));
}
use of org.springframework.cloud.client.loadbalancer.Response in project spring-cloud-gateway by spring-cloud.
the class LoadBalancerServiceInstanceCookieFilter method filter.
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
Response<ServiceInstance> serviceInstanceResponse = exchange.getAttribute(GATEWAY_LOADBALANCER_RESPONSE_ATTR);
if (serviceInstanceResponse == null || !serviceInstanceResponse.hasServer()) {
return chain.filter(exchange);
}
LoadBalancerProperties properties = loadBalancerClientFactory != null ? loadBalancerClientFactory.getProperties(serviceInstanceResponse.getServer().getServiceId()) : loadBalancerProperties;
if (!properties.getStickySession().isAddServiceInstanceCookie()) {
return chain.filter(exchange);
}
String instanceIdCookieName = properties.getStickySession().getInstanceIdCookieName();
if (!StringUtils.hasText(instanceIdCookieName)) {
return chain.filter(exchange);
}
ServerWebExchange newExchange = exchange.mutate().request(exchange.getRequest().mutate().headers((headers) -> {
List<String> cookieHeaders = new ArrayList<>(headers.getOrEmpty(HttpHeaders.COOKIE));
String serviceInstanceCookie = new HttpCookie(instanceIdCookieName, serviceInstanceResponse.getServer().getInstanceId()).toString();
cookieHeaders.add(serviceInstanceCookie);
headers.put(HttpHeaders.COOKIE, cookieHeaders);
}).build()).build();
return chain.filter(newExchange);
}
use of org.springframework.cloud.client.loadbalancer.Response in project spring-cloud-gateway by spring-cloud.
the class ReactiveLoadBalancerClientFilter method filter.
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
String schemePrefix = exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR);
if (url == null || (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {
return chain.filter(exchange);
}
// preserve the original url
addOriginalRequestUrl(exchange, url);
if (log.isTraceEnabled()) {
log.trace(ReactiveLoadBalancerClientFilter.class.getSimpleName() + " url before: " + url);
}
URI requestUri = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
String serviceId = requestUri.getHost();
Set<LoadBalancerLifecycle> supportedLifecycleProcessors = LoadBalancerLifecycleValidator.getSupportedLifecycleProcessors(clientFactory.getInstances(serviceId, LoadBalancerLifecycle.class), RequestDataContext.class, ResponseData.class, ServiceInstance.class);
DefaultRequest<RequestDataContext> lbRequest = new DefaultRequest<>(new RequestDataContext(new RequestData(exchange.getRequest()), getHint(serviceId)));
return choose(lbRequest, serviceId, supportedLifecycleProcessors).doOnNext(response -> {
if (!response.hasServer()) {
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.DISCARD, lbRequest, response)));
throw NotFoundException.create(properties.isUse404(), "Unable to find instance for " + url.getHost());
}
ServiceInstance retrievedInstance = response.getServer();
URI uri = exchange.getRequest().getURI();
// if the `lb:<scheme>` mechanism was used, use `<scheme>` as the default,
// if the loadbalancer doesn't provide one.
String overrideScheme = retrievedInstance.isSecure() ? "https" : "http";
if (schemePrefix != null) {
overrideScheme = url.getScheme();
}
DelegatingServiceInstance serviceInstance = new DelegatingServiceInstance(retrievedInstance, overrideScheme);
URI requestUrl = reconstructURI(serviceInstance, uri);
if (log.isTraceEnabled()) {
log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
}
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
exchange.getAttributes().put(GATEWAY_LOADBALANCER_RESPONSE_ATTR, response);
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStartRequest(lbRequest, response));
}).then(chain.filter(exchange)).doOnError(throwable -> supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(new CompletionContext<ResponseData, ServiceInstance, RequestDataContext>(CompletionContext.Status.FAILED, throwable, lbRequest, exchange.getAttribute(GATEWAY_LOADBALANCER_RESPONSE_ATTR))))).doOnSuccess(aVoid -> supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(new CompletionContext<ResponseData, ServiceInstance, RequestDataContext>(CompletionContext.Status.SUCCESS, lbRequest, exchange.getAttribute(GATEWAY_LOADBALANCER_RESPONSE_ATTR), new ResponseData(exchange.getResponse(), new RequestData(exchange.getRequest()))))));
}
use of org.springframework.cloud.client.loadbalancer.Response in project spring-cloud-gateway by spring-cloud.
the class ReactiveLoadBalancerClientFilterTests method mockExchange.
@SuppressWarnings({ "rawtypes", "unchecked" })
private ServerWebExchange mockExchange(ServiceInstance serviceInstance, LoadBalancerLifecycle lifecycleProcessor, boolean shouldThrowException) {
Response response;
when(lifecycleProcessor.supports(any(Class.class), any(Class.class), any(Class.class))).thenReturn(true);
MockServerHttpRequest request = MockServerHttpRequest.get("http://localhost/get?a=b").build();
URI lbUri = URI.create("lb://service1?a=b");
ServerWebExchange serverWebExchange = MockServerWebExchange.from(request);
if (serviceInstance == null) {
response = new EmptyResponse();
} else {
response = new DefaultResponse(serviceInstance);
}
serverWebExchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, lbUri);
serverWebExchange.getAttributes().put(GATEWAY_ORIGINAL_REQUEST_URL_ATTR, new LinkedHashSet<>());
serverWebExchange.getAttributes().put(GATEWAY_LOADBALANCER_RESPONSE_ATTR, response);
RoundRobinLoadBalancer loadBalancer = mock(RoundRobinLoadBalancer.class);
when(loadBalancer.choose(any(Request.class))).thenReturn(Mono.just(response));
when(clientFactory.getInstance("service1", ReactorServiceInstanceLoadBalancer.class)).thenReturn(loadBalancer);
Map<String, LoadBalancerLifecycle> lifecycleProcessors = new HashMap<>();
lifecycleProcessors.put("service1", lifecycleProcessor);
when(clientFactory.getInstances("service1", LoadBalancerLifecycle.class)).thenReturn(lifecycleProcessors);
if (shouldThrowException) {
when(chain.filter(any())).thenReturn(Mono.error(new UnsupportedOperationException()));
} else {
when(chain.filter(any())).thenReturn(Mono.empty());
}
return serverWebExchange;
}
use of org.springframework.cloud.client.loadbalancer.Response in project matecloud by matevip.
the class GrayReactiveLoadBalancerClientFilter method filter.
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI url = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
String schemePrefix = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR);
// 判断url 前缀 如不是lb开头的就进行下一个过滤器
if (url == null || (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {
return chain.filter(exchange);
}
// 根据网关的原始网址。替换exchange url为 http://IP:PORT/path 路径的url
// preserve the original url
ServerWebExchangeUtils.addOriginalRequestUrl(exchange, url);
if (log.isTraceEnabled()) {
log.trace(ReactiveLoadBalancerClientFilter.class.getSimpleName() + " url before: " + url);
}
// 这里呢会进行调用真正的负载均衡
return choose(exchange).doOnNext(response -> {
if (!response.hasServer()) {
throw NotFoundException.create(properties.isUse404(), "Unable to find instance for " + url.getHost());
}
URI uri = exchange.getRequest().getURI();
// if the `lb:<scheme>` mechanism was used, use `<scheme>` as the default,
// if the loadbalancer doesn't provide one.
String overrideScheme = null;
if (schemePrefix != null) {
overrideScheme = url.getScheme();
}
DelegatingServiceInstance serviceInstance = new DelegatingServiceInstance(response.getServer(), overrideScheme);
URI requestUrl = LoadBalancerUriTools.reconstructURI(serviceInstance, uri);
if (log.isTraceEnabled()) {
log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
}
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, requestUrl);
}).then(chain.filter(exchange));
}
Aggregations