Search in sources :

Example 1 with Request

use of org.springframework.cloud.client.loadbalancer.Request 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));
}
Also used : GlobalFilter(org.springframework.cloud.gateway.filter.GlobalFilter) Ordered(org.springframework.core.Ordered) Response(org.springframework.cloud.client.loadbalancer.Response) GatewayFilterChain(org.springframework.cloud.gateway.filter.GatewayFilterChain) ServerWebExchangeUtils(org.springframework.cloud.gateway.support.ServerWebExchangeUtils) DefaultRequest(org.springframework.cloud.client.loadbalancer.DefaultRequest) Autowired(org.springframework.beans.factory.annotation.Autowired) Mono(reactor.core.publisher.Mono) NotFoundException(org.springframework.cloud.gateway.support.NotFoundException) LoadBalancerClientFactory(org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory) LoadBalancerUriTools(org.springframework.cloud.client.loadbalancer.LoadBalancerUriTools) ServerWebExchange(org.springframework.web.server.ServerWebExchange) Objects(java.util.Objects) Slf4j(lombok.extern.slf4j.Slf4j) DelegatingServiceInstance(org.springframework.cloud.gateway.support.DelegatingServiceInstance) InMemoryRouteRepository(com.hummer.doorgod.service.domain.route.InMemoryRouteRepository) Map(java.util.Map) Request(org.springframework.cloud.client.loadbalancer.Request) ReactiveLoadBalancerClientFilter(org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter) ServiceInstance(org.springframework.cloud.client.ServiceInstance) URI(java.net.URI) LoadBalancerConfig(com.hummer.doorgod.service.domain.configuration.LoadBalancerConfig) BaseReactorServiceInstanceLoadbalancer(com.hummer.doorgod.service.domain.loadbalancer.BaseReactorServiceInstanceLoadbalancer) Route(org.springframework.cloud.gateway.route.Route) DelegatingServiceInstance(org.springframework.cloud.gateway.support.DelegatingServiceInstance) ReactiveLoadBalancerClientFilter(org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter) URI(java.net.URI)

Example 2 with Request

use of org.springframework.cloud.client.loadbalancer.Request in project hummer-framework by hummer-team.

the class HostByRandomWeightLoadBalancer method choose.

@Override
protected Mono<Instance> choose(Request request, String serviceId, List<Instance> instances) {
    return Mono.fromCallable(() -> {
        List<Instance> instancesToChoose = instances;
        NacosDiscoveryProperties discoveryProperties = SpringApplicationContext.getBean(NacosDiscoveryProperties.class);
        if (StringUtils.isNotBlank(discoveryProperties.getClusterName())) {
            List<Instance> sameClusterInstances = instances.stream().filter(instance -> Objects.equals(discoveryProperties.getClusterName(), instance.getClusterName())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(sameClusterInstances)) {
                instancesToChoose = sameClusterInstances;
            } else {
                LOGGER.warn("A cross-cluster call occurs,name = {}, clusterName = {}, instance = {}", serviceId, discoveryProperties.getClusterName(), instances);
            }
        }
        // notice: 2.2.7-RELEASE ExtendBalancer.getHostByRandomWeight2(instancesToChoose)
        return Balancer.getHostByRandomWeight(instancesToChoose);
    });
}
Also used : Response(org.springframework.cloud.client.loadbalancer.Response) Logger(org.slf4j.Logger) LoggerFactory(org.slf4j.LoggerFactory) SpringApplicationContext(com.hummer.core.SpringApplicationContext) Mono(reactor.core.publisher.Mono) StringUtils(org.apache.commons.lang3.StringUtils) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) NacosDiscoveryProperties(com.alibaba.cloud.nacos.NacosDiscoveryProperties) Component(org.springframework.stereotype.Component) List(java.util.List) ReactorServiceInstanceLoadBalancer(org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer) Instance(com.alibaba.nacos.api.naming.pojo.Instance) CollectionUtils(org.springframework.util.CollectionUtils) Request(org.springframework.cloud.client.loadbalancer.Request) ServiceInstance(org.springframework.cloud.client.ServiceInstance) Instance(com.alibaba.nacos.api.naming.pojo.Instance) ServiceInstance(org.springframework.cloud.client.ServiceInstance) NacosDiscoveryProperties(com.alibaba.cloud.nacos.NacosDiscoveryProperties)

Example 3 with Request

use of org.springframework.cloud.client.loadbalancer.Request in project spring-cloud-gateway by spring-cloud.

the class ReactiveLoadBalancerClientFilterTests method shouldPassRequestToLoadBalancer.

@SuppressWarnings({ "rawtypes" })
@Test
void shouldPassRequestToLoadBalancer() {
    String hint = "test";
    when(loadBalancerProperties.getHint()).thenReturn(buildHints(hint));
    when(clientFactory.getProperties(any())).thenReturn(loadBalancerProperties);
    MockServerHttpRequest request = MockServerHttpRequest.get("http://localhost/get?a=b").build();
    URI lbUri = URI.create("lb://service1?a=b");
    ServerWebExchange serverWebExchange = mock(ServerWebExchange.class);
    when(serverWebExchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)).thenReturn(lbUri);
    when(serverWebExchange.getRequiredAttribute(GATEWAY_ORIGINAL_REQUEST_URL_ATTR)).thenReturn(new LinkedHashSet<>());
    when(serverWebExchange.getRequest()).thenReturn(request);
    RoundRobinLoadBalancer loadBalancer = mock(RoundRobinLoadBalancer.class);
    when(loadBalancer.choose(any(Request.class))).thenReturn(Mono.just(new DefaultResponse(new DefaultServiceInstance("myservice1", "service1", "localhost", 8080, false))));
    when(clientFactory.getInstance("service1", ReactorServiceInstanceLoadBalancer.class)).thenReturn(loadBalancer);
    when(chain.filter(any())).thenReturn(Mono.empty());
    filter.filter(serverWebExchange, chain);
    verify(loadBalancer).choose(argThat((Request passedRequest) -> ((RequestDataContext) passedRequest.getContext()).getClientRequest().getUrl().equals(request.getURI()) && ((RequestDataContext) passedRequest.getContext()).getHint().equals(hint)));
}
Also used : DefaultResponse(org.springframework.cloud.client.loadbalancer.DefaultResponse) ServerWebExchange(org.springframework.web.server.ServerWebExchange) MockServerWebExchange(org.springframework.mock.web.server.MockServerWebExchange) DefaultServiceInstance(org.springframework.cloud.client.DefaultServiceInstance) MockServerHttpRequest(org.springframework.mock.http.server.reactive.MockServerHttpRequest) Request(org.springframework.cloud.client.loadbalancer.Request) MockServerHttpRequest(org.springframework.mock.http.server.reactive.MockServerHttpRequest) RoundRobinLoadBalancer(org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer) RequestDataContext(org.springframework.cloud.client.loadbalancer.RequestDataContext) URI(java.net.URI) Test(org.junit.jupiter.api.Test)

Example 4 with Request

use of org.springframework.cloud.client.loadbalancer.Request 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;
}
Also used : DefaultResponse(org.springframework.cloud.client.loadbalancer.DefaultResponse) ServerWebExchange(org.springframework.web.server.ServerWebExchange) MockServerWebExchange(org.springframework.mock.web.server.MockServerWebExchange) HashMap(java.util.HashMap) Request(org.springframework.cloud.client.loadbalancer.Request) MockServerHttpRequest(org.springframework.mock.http.server.reactive.MockServerHttpRequest) LoadBalancerLifecycle(org.springframework.cloud.client.loadbalancer.LoadBalancerLifecycle) RoundRobinLoadBalancer(org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer) URI(java.net.URI) Response(org.springframework.cloud.client.loadbalancer.Response) DefaultResponse(org.springframework.cloud.client.loadbalancer.DefaultResponse) EmptyResponse(org.springframework.cloud.client.loadbalancer.EmptyResponse) MockServerHttpRequest(org.springframework.mock.http.server.reactive.MockServerHttpRequest) EmptyResponse(org.springframework.cloud.client.loadbalancer.EmptyResponse)

Aggregations

Request (org.springframework.cloud.client.loadbalancer.Request)4 URI (java.net.URI)3 Response (org.springframework.cloud.client.loadbalancer.Response)3 ServerWebExchange (org.springframework.web.server.ServerWebExchange)3 Objects (java.util.Objects)2 ServiceInstance (org.springframework.cloud.client.ServiceInstance)2 DefaultResponse (org.springframework.cloud.client.loadbalancer.DefaultResponse)2 RoundRobinLoadBalancer (org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer)2 MockServerHttpRequest (org.springframework.mock.http.server.reactive.MockServerHttpRequest)2 MockServerWebExchange (org.springframework.mock.web.server.MockServerWebExchange)2 Mono (reactor.core.publisher.Mono)2 NacosDiscoveryProperties (com.alibaba.cloud.nacos.NacosDiscoveryProperties)1 Instance (com.alibaba.nacos.api.naming.pojo.Instance)1 SpringApplicationContext (com.hummer.core.SpringApplicationContext)1 LoadBalancerConfig (com.hummer.doorgod.service.domain.configuration.LoadBalancerConfig)1 BaseReactorServiceInstanceLoadbalancer (com.hummer.doorgod.service.domain.loadbalancer.BaseReactorServiceInstanceLoadbalancer)1 InMemoryRouteRepository (com.hummer.doorgod.service.domain.route.InMemoryRouteRepository)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1