remove the list of serviceIds and add ServiceListInitializer

This commit is contained in:
Spencer Gibb
2014-10-02 00:42:40 -06:00
parent 2daeed6c00
commit 03e6308335
31 changed files with 113 additions and 128 deletions

View File

@@ -1,24 +0,0 @@
package org.springframework.cloud.client;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Spencer Gibb
* TODO: move org.springframework.cloud.client to a spring-cloud-common project
*/
@Configuration
@EnableConfigurationProperties
@ConditionalOnExpression("${spring.cloud.client.enabled:true}")
public class ClientAutoConfiguration {
@Bean
@ConditionalOnMissingBean(ClientProperties.class)
public ClientProperties clientProperties() {
return new ClientProperties();
}
}

View File

@@ -1,15 +0,0 @@
package org.springframework.cloud.client;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;
/**
* @author Spencer Gibb
*/
@Data
@ConfigurationProperties("spring.cloud.client")
public class ClientProperties {
private List<String> serviceIds;
}

View File

@@ -20,7 +20,7 @@ import static com.netflix.config.ConfigurationManager.APPLICATION_PROPERTIES;
import static com.netflix.config.ConfigurationManager.ENV_CONFIG_NAME;
/**
* Created by sgibb on 7/3/14.
* @author Spencer Gibb
*/
@Configuration
public class ArchaiusAutoConfiguration {

View File

@@ -19,7 +19,7 @@ import org.springframework.core.env.StandardEnvironment;
import org.springframework.util.ReflectionUtils;
/**
* Created by sgibb on 6/27/14.
* @author Spencer Gibb
*/
public class ConfigurableEnvironmentConfiguration extends AbstractConfiguration {
ConfigurableEnvironment environment;

View File

@@ -19,7 +19,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.ClientProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -47,10 +46,4 @@ public class EurekaClientAutoConfiguration {
public EurekaInstanceConfigBean eurekaInstanceConfigBean() {
return new EurekaInstanceConfigBean();
}
@Bean
@ConditionalOnMissingBean(EurekaRibbonInitializer.class)
public EurekaRibbonInitializer eurekaRibbonInitializer(ClientProperties clientProperties) {
return new EurekaRibbonInitializer(clientProperties);
}
}

View File

@@ -1,28 +0,0 @@
package org.springframework.cloud.netflix.eureka;
import com.netflix.config.ConfigurationManager;
import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
import org.springframework.cloud.client.ClientProperties;
/**
* @author Spencer Gibb
*/
public class EurekaRibbonInitializer {
public EurekaRibbonInitializer(ClientProperties clientProperties) {
if (clientProperties.getServiceIds() != null) {
for (String serviceId : clientProperties.getServiceIds()) {
setServiceListClassAndVIP(serviceId);
}
}
}
public static void setServiceListClassAndVIP(String serviceId) {
setProp(serviceId, "NIWSServerListClassName", DiscoveryEnabledNIWSServerList.class.getName());
setProp(serviceId, "DeploymentContextBasedVipAddresses", serviceId); //FIXME: what should this be?
}
private static void setProp(String serviceId, String suffix, String value) {
ConfigurationManager.getConfigInstance().setProperty(serviceId + ".ribbon." + suffix, value);
}
}

View File

@@ -8,7 +8,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
/**
* Created by sgibb on 7/3/14.
* @author Spencer Gibb
*/
@Configuration
@AutoConfigureAfter(ArchaiusAutoConfiguration.class)

View File

@@ -22,7 +22,7 @@ import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* Created by sgibb on 6/27/14.
* @author Spencer Gibb
*/
public class FeignBase {
public static final boolean romePresent =

View File

@@ -7,19 +7,23 @@ import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.ribbon.LoadBalancingTarget;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.ribbon.ServerListInitializer;
import org.springframework.context.annotation.Configuration;
import org.springframework.cloud.netflix.archaius.ConfigurableEnvironmentConfiguration;
import java.net.URI;
/**
* Created by sgibb on 7/3/14.
* @author Spencer Gibb
*/
@Configuration
public class FeignConfigurer {
@Autowired
ConfigurableEnvironmentConfiguration envConfig; //FIXME: howto enforce this?
@Autowired
ServerListInitializer serverListInitializer;
@Autowired
Decoder decoder;
@@ -48,6 +52,7 @@ public class FeignConfigurer {
protected <T> T loadBalance(Feign.Builder builder, Class<T> type, String schemeName) {
String name = URI.create(schemeName).getHost();
serverListInitializer.initialize(name);
return builder.target(LoadBalancingTarget.create(type, schemeName));
}

View File

@@ -17,7 +17,7 @@ import feign.codec.DecodeException;
import feign.codec.Decoder;
/**
* Created by sgibb on 6/26/14.
* @author Spencer Gibb
*/
public class SpringDecoder extends FeignBase implements Decoder {

View File

@@ -20,7 +20,7 @@ import java.util.Collection;
import java.util.List;
/**
* Created by sgibb on 6/26/14.
* @author Spencer Gibb
*/
public class SpringEncoder extends FeignBase implements Encoder {
private static final Logger logger = LoggerFactory.getLogger(SpringEncoder.class);

View File

@@ -13,7 +13,7 @@ import feign.Contract;
import feign.MethodMetadata;
/**
* Created by sgibb on 6/27/14.
* @author Spencer Gibb
*/
public class SpringMvcContract extends Contract.BaseContract {
static final String ACCEPT = "Accept";

View File

@@ -7,7 +7,7 @@ import org.springframework.core.Ordered;
import java.lang.annotation.*;
/**
* Created by sgibb on 6/19/14.
* @author Spencer Gibb
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)

View File

@@ -28,7 +28,7 @@ import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsPoller;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsPoller.MetricsAsJsonPollerListener;
/**
* Created by sgibb on 6/19/14.
* @author Spencer Gibb
*/
@Configuration
public class HystrixConfiguration implements ImportAware {

View File

@@ -5,7 +5,7 @@ import org.springframework.context.annotation.AdviceModeImportSelector;
import org.springframework.context.annotation.AutoProxyRegistrar;
/**
* Created by sgibb on 6/19/14.
* @author Spencer Gibb
*/
public class HystrixConfigurationSelector extends AdviceModeImportSelector<EnableHystrix> {
/**

View File

@@ -1,7 +1,7 @@
package org.springframework.cloud.netflix.hystrix;
/**
* Created by sgibb on 6/19/14.
* @author Spencer Gibb
*/
public interface HystrixConfigurer {
}

View File

@@ -1,11 +1,9 @@
package org.springframework.cloud.netflix.ribbon;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration;
import org.springframework.cloud.netflix.eureka.EurekaRibbonInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestInterceptor;
@@ -21,10 +19,6 @@ import java.util.List;
@AutoConfigureAfter(EurekaClientAutoConfiguration.class)
public class RibbonAutoConfiguration {
//TODO: why doesn't @AutoConfigureAfter(EurekaClientAutoConfiguration.class) do what the following does for order?
@Autowired
EurekaRibbonInitializer eurekaRibbonInitializer;
@Bean
@ConditionalOnMissingBean(RestTemplate.class)
public RestTemplate restTemplate(RibbonInterceptor ribbonInterceptor) {

View File

@@ -3,6 +3,7 @@ package org.springframework.cloud.netflix.ribbon;
import com.netflix.client.ClientFactory;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
@@ -10,8 +11,12 @@ import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
* @author Spencer Gibb
*/
public class RibbonLoadBalancerClient implements LoadBalancerClient {
@Autowired
private ServerListInitializer serverListInitializer;
@Override
public ServiceInstance choose(String serviceId) {
serverListInitializer.initialize(serviceId);
ILoadBalancer loadBalancer = ClientFactory.getNamedLoadBalancer(serviceId);
Server server = loadBalancer.chooseServer(null);
if (server == null) {

View File

@@ -0,0 +1,8 @@
package org.springframework.cloud.netflix.ribbon;
/**
* @author Spencer Gibb
*/
public interface ServerListInitializer {
public void initialize(String serviceId);
}

View File

@@ -0,0 +1,24 @@
package org.springframework.cloud.netflix.ribbon.eureka;
import com.netflix.config.ConfigurationManager;
import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
import org.springframework.cloud.netflix.ribbon.ServerListInitializer;
/**
* @author Spencer Gibb
*/
public class EurekaRibbonInitializer implements ServerListInitializer {
@Override
public void initialize(String serviceId) {
//TODO: should this look more like hibernate spring boot props?
setProp(serviceId, "NIWSServerListClassName", DiscoveryEnabledNIWSServerList.class.getName());
setProp(serviceId, "DeploymentContextBasedVipAddresses", serviceId); //FIXME: what should this be?
}
protected void setProp(String serviceId, String suffix, String value) {
//how to set the namespace properly?
String namespace = "ribbon";
ConfigurationManager.getConfigInstance().setProperty(serviceId + "."+ namespace +"." + suffix, value);
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2013-2014 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.ribbon.eureka;
import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
import org.springframework.cloud.netflix.ribbon.ServerListInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Dave Syer
*
*/
@Configuration
@EnableConfigurationProperties
@ConditionalOnClass(DiscoveryEnabledNIWSServerList.class)
@ConditionalOnExpression("${ribbon.eureka.enabled:true}")
@AutoConfigureBefore(RibbonAutoConfiguration.class)
public class RibbonEurekaAutoConfiguration {
@Bean
@ConditionalOnMissingBean(ServerListInitializer.class)
public ServerListInitializer serverListInitializer() {
return new EurekaRibbonInitializer();
}
}

View File

@@ -13,7 +13,7 @@ import java.util.Map;
import java.util.Set;
/**
* Created by sgibb on 7/10/14.
* @author Spencer Gibb
*/
public class Routes {
private static final Logger logger = LoggerFactory.getLogger(Routes.class);

View File

@@ -4,7 +4,7 @@ import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Created by sgibb on 8/5/14.
* @author Spencer Gibb
*/
@Data
@ConfigurationProperties("zuul.proxy")

View File

@@ -1,7 +1,5 @@
package org.springframework.cloud.netflix.zuul.filters.route;
import static org.springframework.cloud.netflix.eureka.EurekaRibbonInitializer.setServiceListClassAndVIP;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
@@ -18,7 +16,9 @@ import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.actuate.trace.TraceRepository;
import org.springframework.cloud.netflix.ribbon.ServerListInitializer;
import org.springframework.cloud.netflix.zuul.RibbonCommand;
import org.springframework.cloud.netflix.zuul.SpringFilter;
import org.springframework.util.StringUtils;
import com.netflix.client.ClientException;
@@ -27,13 +27,12 @@ import com.netflix.client.http.HttpRequest.Verb;
import com.netflix.client.http.HttpResponse;
import com.netflix.hystrix.exception.HystrixRuntimeException;
import com.netflix.niws.client.http.RestClient;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.netflix.zuul.util.HTTPRequestUtils;
import com.sun.jersey.core.util.MultivaluedMapImpl;
public class RibbonRoutingFilter extends ZuulFilter {
public class RibbonRoutingFilter extends SpringFilter {
private static final Logger LOG = LoggerFactory.getLogger(RibbonRoutingFilter.class);
@@ -72,8 +71,8 @@ public class RibbonRoutingFilter extends ZuulFilter {
String serviceId = (String) context.get("serviceId");
// TODO: can this be set be default? or an implementation of an interface?
setServiceListClassAndVIP(serviceId);
//TODO: should this be an interface or just config?
getBean(ServerListInitializer.class).initialize(serviceId);
RestClient restClient = (RestClient) ClientFactory.getNamedClient(serviceId);

View File

@@ -1,7 +1,7 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.client.ClientAutoConfiguration,\
org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration,\
org.springframework.cloud.netflix.feign.FeignAutoConfiguration,\
org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration,\
org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration,\
org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration,\
org.springframework.cloud.netflix.servo.ServoMetricsAutoConfiguration

View File

@@ -20,7 +20,7 @@ import java.net.URI;
import java.util.*;
/**
* Created by sgibb on 7/29/14.
* @author Spencer Gibb
*/
@Controller
public class EurekaController {

View File

@@ -9,7 +9,7 @@ import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
/**
* Created by sgibb on 6/19/14.
* @author Spencer Gibb
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)

View File

@@ -20,7 +20,7 @@ import java.util.List;
import static com.netflix.turbine.monitor.cluster.AggregateClusterMonitor.AggregatorClusterMonitorConsole;
/**
* Created by sgibb on 7/14/14.
* @author Spencer Gibb
*/
public class SpringAggregatorFactory implements ClusterMonitorFactory<AggDataFromCluster> {
private static final Logger logger = LoggerFactory.getLogger(SpringAggregatorFactory.class);

View File

@@ -12,7 +12,7 @@ import com.netflix.turbine.monitor.cluster.ObservationCriteria;
import com.netflix.turbine.monitor.instance.InstanceUrlClosure;
/**
* Created by sgibb on 7/14/14.
* @author Spencer Gibb
* TODO: convert to ConfigurationProperties (how to do per-cluster configuration?)
*/
public class SpringClusterMonitor extends AggregateClusterMonitor {

View File

@@ -12,7 +12,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
/**
* Created by sgibb on 7/11/14.
* @author Spencer Gibb
*/
@Configuration
@EnableEurekaClient

View File

@@ -99,16 +99,6 @@ public class StoreIntegration {
== Declarative REST Client: Feign
Example application.yml:
```
spring:
cloud:
client:
serviceIds:
- stores
```
Example spring boot app
```
@Configuration
@@ -142,16 +132,6 @@ public interface StoreClient {
== Client Side Load Balancer: Ribbon
Example application.yml:
```
spring:
cloud:
client:
serviceIds:
- stores
```
Usage of `LoadBalancerClient` directly:
```
@@ -160,7 +140,6 @@ public class MyClass {
private LoadBalancerClient loadBalancer;
public void doStuff() {
//"stores" in choose() must match a service in spring.cloud.client.serviceIds
ServiceInstance instance = loadBalancer.choose("stores");
URI storesUri = URI.create(String.format("http://%s:%s", instance.getHost(), instance.getPort()));
// ... do something with the URI
@@ -168,7 +147,7 @@ public class MyClass {
}
```
Indirect usage via `RestTemplate`. Notice the `stores` hostname part, must match a service id in spring.cloud.client.serviceIds:
Indirect usage via `RestTemplate`.
```
public class MyClass {