Applied checkstyle and turned it on by default
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,8 +29,8 @@ import org.springframework.core.annotation.AliasFor;
|
||||
|
||||
/**
|
||||
* Declarative configuration for a load balancer client. Add this annotation to any
|
||||
* <code>@Configuration</code> and then inject a {@link LoadBalancerClientFactory} to access the
|
||||
* client that is created.
|
||||
* <code>@Configuration</code> and then inject a {@link LoadBalancerClientFactory} to
|
||||
* access the client that is created.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@@ -42,25 +42,28 @@ import org.springframework.core.annotation.AliasFor;
|
||||
public @interface LoadBalancerClient {
|
||||
|
||||
/**
|
||||
* Synonym for name (the name of the client)
|
||||
* Synonym for name (the name of the client).
|
||||
*
|
||||
* @see #name()
|
||||
* @return the name of the load balancer client
|
||||
*/
|
||||
@AliasFor("name")
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* The name of the load balancer client, uniquely identifying a set of client resources,
|
||||
* including a load balancer.
|
||||
* The name of the load balancer client, uniquely identifying a set of client
|
||||
* resources, including a load balancer.
|
||||
* @return the name of the load balancer client
|
||||
*/
|
||||
@AliasFor("value")
|
||||
String name() default "";
|
||||
|
||||
/**
|
||||
* A custom <code>@Configuration</code> for the load balancer client. Can contain override
|
||||
* <code>@Bean</code> definition for the pieces that make up the client.
|
||||
* A custom <code>@Configuration</code> for the load balancer client. Can contain
|
||||
* override <code>@Bean</code> definition for the pieces that make up the client.
|
||||
*
|
||||
* @see LoadBalancerClientConfiguration for the defaults
|
||||
* @return configuration classes for the load balancer client.
|
||||
*/
|
||||
Class<?>[] configuration() default {};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,11 +38,14 @@ public class LoadBalancerClientConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServiceInstanceSupplier discoveryClientServiceInstanceSupplier(
|
||||
DiscoveryClient discoveryClient, Environment env, ObjectProvider<CacheManager> cacheManager) {
|
||||
//TODO: bean post processor to enable caching?
|
||||
DiscoveryClientServiceInstanceSupplier delegate = new DiscoveryClientServiceInstanceSupplier(discoveryClient, env);
|
||||
DiscoveryClient discoveryClient, Environment env,
|
||||
ObjectProvider<CacheManager> cacheManager) {
|
||||
// TODO: bean post processor to enable caching?
|
||||
DiscoveryClientServiceInstanceSupplier delegate = new DiscoveryClientServiceInstanceSupplier(
|
||||
discoveryClient, env);
|
||||
if (cacheManager.getIfAvailable() != null) {
|
||||
return new CachingServiceInstanceSupplier(delegate, cacheManager.getIfAvailable());
|
||||
return new CachingServiceInstanceSupplier(delegate,
|
||||
cacheManager.getIfAvailable());
|
||||
}
|
||||
return delegate;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,37 +28,8 @@ import org.springframework.util.StringUtils;
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class LoadBalancerClientConfigurationRegistrar implements ImportBeanDefinitionRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata metadata,
|
||||
BeanDefinitionRegistry registry) {
|
||||
Map<String, Object> attrs = metadata.getAnnotationAttributes(
|
||||
LoadBalancerClients.class.getName(), true);
|
||||
if (attrs != null && attrs.containsKey("value")) {
|
||||
AnnotationAttributes[] clients = (AnnotationAttributes[]) attrs.get("value");
|
||||
for (AnnotationAttributes client : clients) {
|
||||
registerClientConfiguration(registry, getClientName(client),
|
||||
client.get("configuration"));
|
||||
}
|
||||
}
|
||||
if (attrs != null && attrs.containsKey("defaultConfiguration")) {
|
||||
String name;
|
||||
if (metadata.hasEnclosingClass()) {
|
||||
name = "default." + metadata.getEnclosingClassName();
|
||||
} else {
|
||||
name = "default." + metadata.getClassName();
|
||||
}
|
||||
registerClientConfiguration(registry, name,
|
||||
attrs.get("defaultConfiguration"));
|
||||
}
|
||||
Map<String, Object> client = metadata.getAnnotationAttributes(
|
||||
LoadBalancerClient.class.getName(), true);
|
||||
String name = getClientName(client);
|
||||
if (name != null) {
|
||||
registerClientConfiguration(registry, name, client.get("configuration"));
|
||||
}
|
||||
}
|
||||
public class LoadBalancerClientConfigurationRegistrar
|
||||
implements ImportBeanDefinitionRegistrar {
|
||||
|
||||
private static String getClientName(Map<String, Object> client) {
|
||||
if (client == null) {
|
||||
@@ -76,7 +47,7 @@ public class LoadBalancerClientConfigurationRegistrar implements ImportBeanDefin
|
||||
}
|
||||
|
||||
private static void registerClientConfiguration(BeanDefinitionRegistry registry,
|
||||
Object name, Object configuration) {
|
||||
Object name, Object configuration) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(LoadBalancerClientSpecification.class);
|
||||
builder.addConstructorArgValue(name);
|
||||
@@ -85,4 +56,35 @@ public class LoadBalancerClientConfigurationRegistrar implements ImportBeanDefin
|
||||
builder.getBeanDefinition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata metadata,
|
||||
BeanDefinitionRegistry registry) {
|
||||
Map<String, Object> attrs = metadata
|
||||
.getAnnotationAttributes(LoadBalancerClients.class.getName(), true);
|
||||
if (attrs != null && attrs.containsKey("value")) {
|
||||
AnnotationAttributes[] clients = (AnnotationAttributes[]) attrs.get("value");
|
||||
for (AnnotationAttributes client : clients) {
|
||||
registerClientConfiguration(registry, getClientName(client),
|
||||
client.get("configuration"));
|
||||
}
|
||||
}
|
||||
if (attrs != null && attrs.containsKey("defaultConfiguration")) {
|
||||
String name;
|
||||
if (metadata.hasEnclosingClass()) {
|
||||
name = "default." + metadata.getEnclosingClassName();
|
||||
}
|
||||
else {
|
||||
name = "default." + metadata.getClassName();
|
||||
}
|
||||
registerClientConfiguration(registry, name,
|
||||
attrs.get("defaultConfiguration"));
|
||||
}
|
||||
Map<String, Object> client = metadata
|
||||
.getAnnotationAttributes(LoadBalancerClient.class.getName(), true);
|
||||
String name = getClientName(client);
|
||||
if (name != null) {
|
||||
registerClientConfiguration(registry, name, client.get("configuration"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,7 +26,8 @@ import org.springframework.util.Assert;
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class LoadBalancerClientSpecification implements NamedContextFactory.Specification {
|
||||
public class LoadBalancerClientSpecification
|
||||
implements NamedContextFactory.Specification {
|
||||
|
||||
private String name;
|
||||
|
||||
@@ -43,7 +44,7 @@ public class LoadBalancerClientSpecification implements NamedContextFactory.Spec
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
@@ -52,7 +53,7 @@ public class LoadBalancerClientSpecification implements NamedContextFactory.Spec
|
||||
}
|
||||
|
||||
public Class<?>[] getConfiguration() {
|
||||
return configuration;
|
||||
return this.configuration;
|
||||
}
|
||||
|
||||
public void setConfiguration(Class<?>[] configuration) {
|
||||
@@ -63,22 +64,27 @@ public class LoadBalancerClientSpecification implements NamedContextFactory.Spec
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringCreator to = new ToStringCreator(this);
|
||||
to.append("name", name);
|
||||
to.append("configuration", configuration);
|
||||
to.append("name", this.name);
|
||||
to.append("configuration", this.configuration);
|
||||
return to.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
LoadBalancerClientSpecification that = (LoadBalancerClientSpecification) o;
|
||||
return Objects.equals(name, that.name) &&
|
||||
Arrays.equals(configuration, that.configuration);
|
||||
return Objects.equals(this.name, that.name)
|
||||
&& Arrays.equals(this.configuration, that.configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name, configuration);
|
||||
return Objects.hash(this.name, this.configuration);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,8 +27,8 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Convenience annotation that allows user to combine multiple <code>@LoadBalancerClient</code>
|
||||
* annotations on a single class (including in Java 7).
|
||||
* Convenience annotation that allows user to combine multiple
|
||||
* <code>@LoadBalancerClient</code> annotations on a single class (including in Java 7).
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@@ -42,10 +42,12 @@ public @interface LoadBalancerClients {
|
||||
LoadBalancerClient[] value() default {};
|
||||
|
||||
/**
|
||||
* {@link LoadBalancerClientConfigurationRegistrar} creates a {@link LoadBalancerClientSpecification}
|
||||
* with this as an argument. These in turn are added as default contexts in {@link LoadBalancerClientFactory}.
|
||||
* Configuration defined in these classes are used as defaults if values aren't defined via
|
||||
* {@link LoadBalancerClientConfigurationRegistrar} creates a
|
||||
* {@link LoadBalancerClientSpecification} with this as an argument. These in turn are
|
||||
* added as default contexts in {@link LoadBalancerClientFactory}. Configuration
|
||||
* defined in these classes are used as defaults if values aren't defined via
|
||||
* {@link LoadBalancerClient#configuration()}
|
||||
* @return classes for default configurations
|
||||
*/
|
||||
Class<?>[] defaultConfiguration() default {};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,16 +34,20 @@ import org.springframework.context.annotation.Configuration;
|
||||
// @EnableCaching //TODO: how to enforce, or check conditions?
|
||||
// @AutoConfigureBefore(CacheAutoConfiguration.class)
|
||||
public class LoadBalancerAutoConfiguration {
|
||||
|
||||
private final ObjectProvider<List<LoadBalancerClientSpecification>> configurations;
|
||||
|
||||
public LoadBalancerAutoConfiguration(ObjectProvider<List<LoadBalancerClientSpecification>> configurations) {
|
||||
public LoadBalancerAutoConfiguration(
|
||||
ObjectProvider<List<LoadBalancerClientSpecification>> configurations) {
|
||||
this.configurations = configurations;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LoadBalancerClientFactory loadBalancerClientFactory() {
|
||||
LoadBalancerClientFactory clientFactory = new LoadBalancerClientFactory();
|
||||
clientFactory.setConfigurations(configurations.getIfAvailable(Collections::emptyList));
|
||||
clientFactory.setConfigurations(
|
||||
this.configurations.getIfAvailable(Collections::emptyList));
|
||||
return clientFactory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,34 +31,37 @@ import org.springframework.cloud.client.ServiceInstance;
|
||||
*/
|
||||
public class CachingServiceInstanceSupplier implements ServiceInstanceSupplier {
|
||||
|
||||
public static final String SERVICE_INSTANCE_CACHE_NAME = CachingServiceInstanceSupplier.class.getSimpleName()+"Cache";
|
||||
/**
|
||||
* Name of the service cache instance.
|
||||
*/
|
||||
public static final String SERVICE_INSTANCE_CACHE_NAME = CachingServiceInstanceSupplier.class
|
||||
.getSimpleName() + "Cache";
|
||||
|
||||
private final ServiceInstanceSupplier delegate;
|
||||
|
||||
private final Flux<ServiceInstance> serviceInstances;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public CachingServiceInstanceSupplier(ServiceInstanceSupplier delegate, CacheManager cacheManager) {
|
||||
public CachingServiceInstanceSupplier(ServiceInstanceSupplier delegate,
|
||||
CacheManager cacheManager) {
|
||||
this.delegate = delegate;
|
||||
this.serviceInstances = CacheFlux.lookup(key -> {
|
||||
Cache cache = cacheManager.getCache(SERVICE_INSTANCE_CACHE_NAME); //TODO: configurable cache name
|
||||
Cache cache = cacheManager.getCache(SERVICE_INSTANCE_CACHE_NAME); // TODO:
|
||||
// configurable
|
||||
// cache
|
||||
// name
|
||||
List<ServiceInstance> list = cache.get(key, List.class);
|
||||
if (list == null || list.isEmpty()) {
|
||||
return Mono.empty();
|
||||
}
|
||||
return Flux.fromIterable(list)
|
||||
.materialize()
|
||||
.collectList();
|
||||
}, delegate.getServiceId())
|
||||
.onCacheMissResume(this.delegate::get)
|
||||
.andWriteWith((key, signals) -> Flux.fromIterable(signals)
|
||||
.dematerialize()
|
||||
.cast(ServiceInstance.class)
|
||||
.collectList()
|
||||
.doOnNext(instances -> {
|
||||
Cache cache = cacheManager.getCache(SERVICE_INSTANCE_CACHE_NAME);
|
||||
return Flux.fromIterable(list).materialize().collectList();
|
||||
}, delegate.getServiceId()).onCacheMissResume(this.delegate::get)
|
||||
.andWriteWith((key, signals) -> Flux.fromIterable(signals).dematerialize()
|
||||
.cast(ServiceInstance.class).collectList().doOnNext(instances -> {
|
||||
Cache cache = cacheManager
|
||||
.getCache(SERVICE_INSTANCE_CACHE_NAME);
|
||||
cache.put(key, instances);
|
||||
})
|
||||
.then());
|
||||
}).then());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,4 +73,5 @@ public class CachingServiceInstanceSupplier implements ServiceInstanceSupplier {
|
||||
public String getServiceId() {
|
||||
return this.delegate.getServiceId();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,20 +32,23 @@ import static org.springframework.cloud.loadbalancer.support.LoadBalancerClientF
|
||||
public class DiscoveryClientServiceInstanceSupplier implements ServiceInstanceSupplier {
|
||||
|
||||
private final DiscoveryClient delegate;
|
||||
|
||||
private final String serviceId;
|
||||
|
||||
public DiscoveryClientServiceInstanceSupplier(DiscoveryClient delegate, Environment environment) {
|
||||
public DiscoveryClientServiceInstanceSupplier(DiscoveryClient delegate,
|
||||
Environment environment) {
|
||||
this.delegate = delegate;
|
||||
serviceId = environment.getProperty(PROPERTY_NAME);
|
||||
this.serviceId = environment.getProperty(PROPERTY_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<ServiceInstance> get() {
|
||||
List<ServiceInstance> instances = delegate.getInstances(serviceId);
|
||||
List<ServiceInstance> instances = this.delegate.getInstances(this.serviceId);
|
||||
return Flux.fromIterable(instances);
|
||||
}
|
||||
|
||||
public String getServiceId() {
|
||||
return this.serviceId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,15 +22,23 @@ import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalanc
|
||||
import org.springframework.cloud.client.loadbalancer.reactive.Request;
|
||||
import org.springframework.cloud.client.loadbalancer.reactive.Response;
|
||||
|
||||
/**
|
||||
* A Reactor based implementation of {@link ReactiveLoadBalancer}.
|
||||
*
|
||||
* @param <T> - type of the response
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public interface ReactorLoadBalancer<T> extends ReactiveLoadBalancer<T> {
|
||||
|
||||
/**
|
||||
* Choose the next server based on the load balancing algorithm
|
||||
* @param request
|
||||
* @return
|
||||
* Choose the next server based on the load balancing algorithm.
|
||||
* @param request - an input request
|
||||
* @return - mono of response
|
||||
*/
|
||||
Mono<Response<T>> choose(Request request);
|
||||
|
||||
default Mono<Response<T>> choose() {
|
||||
return choose(REQUEST);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,38 +38,43 @@ public class RoundRobinLoadBalancer implements ReactorLoadBalancer<ServiceInstan
|
||||
private static final Log log = LogFactory.getLog(RoundRobinLoadBalancer.class);
|
||||
|
||||
private final AtomicInteger position;
|
||||
|
||||
private final ObjectProvider<ServiceInstanceSupplier> serviceInstanceSupplier;
|
||||
|
||||
private final String serviceId;
|
||||
|
||||
public RoundRobinLoadBalancer(String serviceId, ObjectProvider<ServiceInstanceSupplier> serviceInstanceSupplier) {
|
||||
public RoundRobinLoadBalancer(String serviceId,
|
||||
ObjectProvider<ServiceInstanceSupplier> serviceInstanceSupplier) {
|
||||
this(serviceId, serviceInstanceSupplier, new Random().nextInt(1000));
|
||||
}
|
||||
|
||||
public RoundRobinLoadBalancer(String serviceId, ObjectProvider<ServiceInstanceSupplier> serviceInstanceSupplier,
|
||||
int seedPosition) {
|
||||
public RoundRobinLoadBalancer(String serviceId,
|
||||
ObjectProvider<ServiceInstanceSupplier> serviceInstanceSupplier,
|
||||
int seedPosition) {
|
||||
this.serviceId = serviceId;
|
||||
this.serviceInstanceSupplier = serviceInstanceSupplier;
|
||||
this.position = new AtomicInteger(seedPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* see original https://github.com/Netflix/ocelli/blob/master/ocelli-core/src/main/java/netflix/ocelli/loadbalancer/RoundRobinLoadBalancer.java
|
||||
*/
|
||||
// see original
|
||||
// https://github.com/Netflix/ocelli/blob/master/ocelli-core/
|
||||
// src/main/java/netflix/ocelli/loadbalancer/RoundRobinLoadBalancer.java
|
||||
public Mono<Response<ServiceInstance>> choose(Request request) {
|
||||
// TODO: move supplier to Request?
|
||||
ServiceInstanceSupplier supplier = serviceInstanceSupplier.getIfAvailable();
|
||||
ServiceInstanceSupplier supplier = this.serviceInstanceSupplier.getIfAvailable();
|
||||
return supplier.get().collectList().map(instances -> {
|
||||
if (instances.isEmpty()) {
|
||||
log.warn("No servers available for service: " + this.serviceId);
|
||||
return new EmptyResponse();
|
||||
}
|
||||
// TODO: enforce order?
|
||||
int pos = Math.abs(position.incrementAndGet());
|
||||
int pos = Math.abs(this.position.incrementAndGet());
|
||||
|
||||
ServiceInstance instance = instances.get(pos % instances.size());
|
||||
|
||||
return new DefaultResponse(instance);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,4 +28,5 @@ import org.springframework.cloud.client.ServiceInstance;
|
||||
public interface ServiceInstanceSupplier extends Supplier<Flux<ServiceInstance>> {
|
||||
|
||||
String getServiceId();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,9 +29,17 @@ import org.springframework.core.env.Environment;
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class LoadBalancerClientFactory extends NamedContextFactory<LoadBalancerClientSpecification> {
|
||||
public class LoadBalancerClientFactory
|
||||
extends NamedContextFactory<LoadBalancerClientSpecification> {
|
||||
|
||||
/**
|
||||
* Property source name for load balancer.
|
||||
*/
|
||||
public static final String NAMESPACE = "loadbalancer";
|
||||
|
||||
/**
|
||||
* Property for client name within the load balancer namespace.
|
||||
*/
|
||||
public static final String PROPERTY_NAME = NAMESPACE + ".client.name";
|
||||
|
||||
public LoadBalancerClientFactory() {
|
||||
@@ -43,4 +51,3 @@ public class LoadBalancerClientFactory extends NamedContextFactory<LoadBalancerC
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,14 +16,25 @@
|
||||
|
||||
package org.springframework.cloud.loadbalancer.support;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.loadbalancer.core.ServiceInstanceSupplier;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
public class ServiceInstanceSuppliers {
|
||||
/**
|
||||
* Utility class for service instances.
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public final class ServiceInstanceSuppliers {
|
||||
|
||||
public static ServiceInstanceSupplier from(String serviceId, ServiceInstance... instances) {
|
||||
private ServiceInstanceSuppliers() {
|
||||
throw new IllegalStateException("Can't instantiate a utility class");
|
||||
}
|
||||
|
||||
public static ServiceInstanceSupplier from(String serviceId,
|
||||
ServiceInstance... instances) {
|
||||
return new ServiceInstanceSupplier() {
|
||||
@Override
|
||||
public Flux<ServiceInstance> get() {
|
||||
@@ -37,7 +48,9 @@ public class ServiceInstanceSuppliers {
|
||||
};
|
||||
}
|
||||
|
||||
public static ObjectProvider<ServiceInstanceSupplier> toProvider(String serviceId, ServiceInstance... instances) {
|
||||
public static ObjectProvider<ServiceInstanceSupplier> toProvider(String serviceId,
|
||||
ServiceInstance... instances) {
|
||||
return new SimpleObjectProvider<>(from(serviceId, instances));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,12 @@ package org.springframework.cloud.loadbalancer.support;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
|
||||
/**
|
||||
* Wrapper for {@link ObjectProvider}.
|
||||
*
|
||||
* @param <T> type of the object to fetch
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class SimpleObjectProvider<T> implements ObjectProvider<T> {
|
||||
|
||||
private final T object;
|
||||
@@ -46,4 +52,5 @@ public class SimpleObjectProvider<T> implements ObjectProvider<T> {
|
||||
public T getObject() throws BeansException {
|
||||
return this.object;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -59,19 +59,21 @@ public class LoadBalancerTest {
|
||||
@Test
|
||||
public void roundRobbinLoadbalancerWorks() {
|
||||
ReactiveLoadBalancer<ServiceInstance> reactiveLoadBalancer = this.clientFactory
|
||||
.getInstance("myservice", ReactiveLoadBalancer.class, ServiceInstance.class);
|
||||
.getInstance("myservice", ReactiveLoadBalancer.class,
|
||||
ServiceInstance.class);
|
||||
|
||||
assertThat(reactiveLoadBalancer).isInstanceOf(RoundRobinLoadBalancer.class);
|
||||
assertThat(reactiveLoadBalancer).isInstanceOf(ReactorLoadBalancer.class);
|
||||
ReactorLoadBalancer<ServiceInstance> loadBalancer = (ReactorLoadBalancer<ServiceInstance>) reactiveLoadBalancer;
|
||||
|
||||
//order dependent on seedPosition -1 of RoundRobinLoadBalancer
|
||||
// order dependent on seedPosition -1 of RoundRobinLoadBalancer
|
||||
List<String> hosts = Arrays.asList("a.host", "c.host", "b.host-secure", "a.host");
|
||||
|
||||
assertLoadBalancer(loadBalancer, hosts);
|
||||
}
|
||||
|
||||
private void assertLoadBalancer(ReactorLoadBalancer<ServiceInstance> loadBalancer, List<String> hosts) {
|
||||
private void assertLoadBalancer(ReactorLoadBalancer<ServiceInstance> loadBalancer,
|
||||
List<String> hosts) {
|
||||
for (String host : hosts) {
|
||||
Mono<Response<ServiceInstance>> source = loadBalancer.choose();
|
||||
StepVerifier.create(source).consumeNextWith(response -> {
|
||||
@@ -80,13 +82,13 @@ public class LoadBalancerTest {
|
||||
|
||||
ServiceInstance instance = response.getServer();
|
||||
assertThat(instance).isNotNull();
|
||||
assertThat(instance.getHost())
|
||||
.as("instance host is incorrent %s", host)
|
||||
assertThat(instance.getHost()).as("instance host is incorrent %s", host)
|
||||
.isEqualTo(host);
|
||||
|
||||
if (host.contains("secure")) {
|
||||
assertThat(instance.isSecure()).isTrue();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
assertThat(instance.isSecure()).isFalse();
|
||||
}
|
||||
|
||||
@@ -97,8 +99,10 @@ public class LoadBalancerTest {
|
||||
|
||||
@Test
|
||||
public void emptyHosts() {
|
||||
ResolvableType type = ResolvableType.forClassWithGenerics(ReactorLoadBalancer.class, ServiceInstance.class);
|
||||
ReactorLoadBalancer<ServiceInstance> loadBalancer = this.clientFactory.getInstance("unknownservice", type);
|
||||
ResolvableType type = ResolvableType
|
||||
.forClassWithGenerics(ReactorLoadBalancer.class, ServiceInstance.class);
|
||||
ReactorLoadBalancer<ServiceInstance> loadBalancer = this.clientFactory
|
||||
.getInstance("unknownservice", type);
|
||||
|
||||
assertThat(loadBalancer).isInstanceOf(RoundRobinLoadBalancer.class);
|
||||
|
||||
@@ -113,13 +117,15 @@ public class LoadBalancerTest {
|
||||
public void staticConfigurationWorks() {
|
||||
String serviceId = "test1";
|
||||
RoundRobinLoadBalancer loadBalancer = new RoundRobinLoadBalancer(serviceId,
|
||||
ServiceInstanceSuppliers.toProvider(serviceId, instance(serviceId, "1.host", false),
|
||||
ServiceInstanceSuppliers.toProvider(serviceId,
|
||||
instance(serviceId, "1.host", false),
|
||||
instance(serviceId, "2.host-secure", true)),
|
||||
-1);
|
||||
assertLoadBalancer(loadBalancer, Arrays.asList("1.host", "2.host-secure"));
|
||||
}
|
||||
|
||||
private DefaultServiceInstance instance(String serviceId, String host, boolean secure) {
|
||||
private DefaultServiceInstance instance(String serviceId, String host,
|
||||
boolean secure) {
|
||||
return new DefaultServiceInstance(serviceId, host, 80, secure);
|
||||
}
|
||||
|
||||
@@ -127,18 +133,22 @@ public class LoadBalancerTest {
|
||||
@SpringBootConfiguration
|
||||
@LoadBalancerClients({
|
||||
@LoadBalancerClient(name = "myservice", configuration = MyServiceConfig.class),
|
||||
@LoadBalancerClient(name = "unknownservice", configuration = MyServiceConfig.class),
|
||||
})
|
||||
@LoadBalancerClient(name = "unknownservice", configuration = MyServiceConfig.class), })
|
||||
@EnableCaching
|
||||
protected static class Config { }
|
||||
protected static class Config {
|
||||
|
||||
}
|
||||
|
||||
protected static class MyServiceConfig {
|
||||
|
||||
@Bean
|
||||
public RoundRobinLoadBalancer roundRobinContextLoadBalancer(LoadBalancerClientFactory clientFactory, Environment env) {
|
||||
public RoundRobinLoadBalancer roundRobinContextLoadBalancer(
|
||||
LoadBalancerClientFactory clientFactory, Environment env) {
|
||||
String serviceId = clientFactory.getName(env);
|
||||
return new RoundRobinLoadBalancer(serviceId,
|
||||
clientFactory.getLazyProvider(serviceId, ServiceInstanceSupplier.class),
|
||||
-1);
|
||||
return new RoundRobinLoadBalancer(serviceId, clientFactory
|
||||
.getLazyProvider(serviceId, ServiceInstanceSupplier.class), -1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,32 +5,23 @@ spring:
|
||||
simple:
|
||||
instances:
|
||||
myservice:
|
||||
-
|
||||
service-id: myservice
|
||||
uri: http://a.host
|
||||
-
|
||||
service-id: myservice
|
||||
uri: http://c.host
|
||||
-
|
||||
service-id: myservice
|
||||
uri: https://b.host-secure
|
||||
- service-id: myservice
|
||||
uri: http://a.host
|
||||
- service-id: myservice
|
||||
uri: http://c.host
|
||||
- service-id: myservice
|
||||
uri: https://b.host-secure
|
||||
anotherservice:
|
||||
-
|
||||
service-id: myservice
|
||||
uri: http://d.host
|
||||
-
|
||||
service-id: myservice
|
||||
uri: http://f.host
|
||||
-
|
||||
service-id: myservice
|
||||
uri: https://e.host
|
||||
- service-id: myservice
|
||||
uri: http://d.host
|
||||
- service-id: myservice
|
||||
uri: http://f.host
|
||||
- service-id: myservice
|
||||
uri: https://e.host
|
||||
thirdservice:
|
||||
-
|
||||
service-id: myservice
|
||||
uri: http://g.host
|
||||
-
|
||||
service-id: myservice
|
||||
uri: http://h.host
|
||||
-
|
||||
service-id: myservice
|
||||
uri: https://i.host
|
||||
- service-id: myservice
|
||||
uri: http://g.host
|
||||
- service-id: myservice
|
||||
uri: http://h.host
|
||||
- service-id: myservice
|
||||
uri: https://i.host
|
||||
|
||||
Reference in New Issue
Block a user