提交 196be004 编写于 作者: A Allen Wang

Rename some methods in ClientOptions. Use raw content source for...

Rename some methods in ClientOptions. Use raw content source for HttpClientRequest if set. Set correct hystrix properties from Ribbon properties. Parse cache key templates.
上级 4aeb4f10
package com.netflix.ribbonclientextensions;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.IClientConfigKey;
import com.netflix.loadbalancer.Server;
import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
public final class ClientOptions {
......@@ -20,14 +16,13 @@ public final class ClientOptions {
public static ClientOptions create() {
return new ClientOptions();
}
public ClientOptions useEurekaDynamicServerList(String vipAddress) {
options.put(IClientConfigKey.CommonKeys.NIWSServerListClassName, DiscoveryEnabledNIWSServerList.class.getName());
options.put(IClientConfigKey.CommonKeys.DeploymentContextBasedVipAddresses, vipAddress);
public ClientOptions withDiscoveryServiceIdentifier(String identifier) {
options.put(IClientConfigKey.CommonKeys.DeploymentContextBasedVipAddresses, identifier);
return this;
}
public ClientOptions useConfigurationBasedServerList(String serverList) {
public ClientOptions withConfigurationBasedServerList(String serverList) {
options.put(IClientConfigKey.CommonKeys.ListOfServers, serverList);
return this;
}
......
......@@ -24,6 +24,7 @@ public class HttpRequestBuilder<T> extends RequestBuilder<T> {
private HystrixObservableCommand.Setter setter;
private Map<String, Object> vars;
private ParsedTemplate parsedUriTemplate;
private RawContentSource<?> rawContentSource;
HttpRequestBuilder(HttpClient<ByteBuf, ByteBuf> client, HttpRequestTemplate<T> requestTemplate, HystrixObservableCommand.Setter setter) {
this.requestTemplate = requestTemplate;
......@@ -43,16 +44,12 @@ public class HttpRequestBuilder<T> extends RequestBuilder<T> {
vars.put(key, value.toString());
return this;
}
public HttpRequestBuilder<T> withContentSource(ContentSource<ByteBuf> source) {
return this;
}
public HttpRequestBuilder<T> withRawContentSource(RawContentSource<?> raw) {
this.rawContentSource = raw;
return this;
}
@Override
public RibbonRequest<T> build() {
return new HttpRequest<T>(this);
......@@ -65,11 +62,18 @@ public class HttpRequestBuilder<T> extends RequestBuilder<T> {
} catch (TemplateParsingException e) {
throw new HystrixBadRequestException("Problem parsing the URI template", e);
}
return HttpClientRequest.create(requestTemplate.method(), uri);
HttpClientRequest<ByteBuf> request = HttpClientRequest.create(requestTemplate.method(), uri);
if (rawContentSource != null) {
request.withRawContentSource(rawContentSource);
}
return request;
}
String cacheKey() {
return requestTemplate.cacheKeyTemplate();
String cacheKey() throws TemplateParsingException {
if (requestTemplate.hystrixCacheKeyTemplate() == null) {
return null;
}
return TemplateParser.toData(vars, requestTemplate.hystrixCacheKeyTemplate());
}
Map<String, Object> requestProperties() {
......
......@@ -37,10 +37,28 @@ public class HttpRequestTemplate<T> implements RequestTemplate<T, HttpClientResp
private ResponseValidator<HttpClientResponse<ByteBuf>> transformer;
private HttpMethod method;
private String name;
private List<CacheProvider<T>> cacheProviders;
private String cacheKeyTemplate;
private List<CacheProviderWithKeyTemplate<T>> cacheProviders;
private ParsedTemplate hystrixCacheKeyTemplate;
private Map<String, ParsedTemplate> parsedTemplates;
private Class<? extends T> classType;
private int concurrentRequestLimit;
static class CacheProviderWithKeyTemplate<T> {
private ParsedTemplate keyTemplate;
private CacheProvider<T> provider;
public CacheProviderWithKeyTemplate(ParsedTemplate keyTemplate,
CacheProvider<T> provider) {
super();
this.keyTemplate = keyTemplate;
this.provider = provider;
}
public final ParsedTemplate getKeyTemplate() {
return keyTemplate;
}
public final CacheProvider<T> getProvider() {
return provider;
}
}
public HttpRequestTemplate(String name, HttpResourceGroup group, HttpClient<ByteBuf, ByteBuf> client, Class<? extends T> classType) {
this.client = client;
......@@ -49,14 +67,16 @@ public class HttpRequestTemplate<T> implements RequestTemplate<T, HttpClientResp
LoadBalancingRxClient<?, ? ,?> ribbonClient = (LoadBalancingRxClient<?, ? ,?>) client;
maxResponseTime = ribbonClient.getResponseTimeOut();
clientName = ribbonClient.getName();
concurrentRequestLimit = ribbonClient.getMaxConcurrentRequests();
} else {
clientName = client.getClass().getName();
maxResponseTime = -1;
concurrentRequestLimit = -1;
}
this.name = name;
// default method to GET
method = HttpMethod.GET;
cacheProviders = new LinkedList<CacheProvider<T>>();
cacheProviders = new LinkedList<CacheProviderWithKeyTemplate<T>>();
parsedTemplates = new HashMap<String, ParsedTemplate>();
}
......@@ -71,8 +91,15 @@ public class HttpRequestTemplate<T> implements RequestTemplate<T, HttpClientResp
// TODO: apply hystrix properties passed in to the template
if (setter == null) {
setter = HystrixObservableCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(clientName))
.andCommandKey(HystrixCommandKey.Factory.asKey(name()))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter().withExecutionIsolationThreadTimeoutInMilliseconds(maxResponseTime));
.andCommandKey(HystrixCommandKey.Factory.asKey(name()));
if (maxResponseTime > 0) {
setter.andCommandPropertiesDefaults(
HystrixCommandProperties.Setter().withExecutionIsolationThreadTimeoutInMilliseconds(maxResponseTime));
}
if (concurrentRequestLimit > 0) {
setter.andCommandPropertiesDefaults(
HystrixCommandProperties.Setter().withExecutionIsolationSemaphoreMaxConcurrentRequests(concurrentRequestLimit));
}
}
return new HttpRequestBuilder<T>(client, this, setter);
}
......@@ -103,23 +130,23 @@ public class HttpRequestTemplate<T> implements RequestTemplate<T, HttpClientResp
@Override
public HttpRequestTemplate<T> withRequestCacheKey(
String cacheKeyTemplate) {
this.cacheKeyTemplate = cacheKeyTemplate;
this.hystrixCacheKeyTemplate = createParsedTemplate(cacheKeyTemplate);
return this;
}
@Override
public HttpRequestTemplate<T> addCacheProvider(String keyTemplate,
CacheProvider<T> cacheProvider) {
this.cacheKeyTemplate = keyTemplate;
cacheProviders.add(cacheProvider);
ParsedTemplate template = createParsedTemplate(keyTemplate);
cacheProviders.add(new CacheProviderWithKeyTemplate<T>(template, cacheProvider));
return this;
}
String cacheKeyTemplate() {
return cacheKeyTemplate;
ParsedTemplate hystrixCacheKeyTemplate() {
return hystrixCacheKeyTemplate;
}
List<CacheProvider<T>> cacheProviders() {
List<CacheProviderWithKeyTemplate<T>> cacheProviders() {
return cacheProviders;
}
......
package com.netflix.ribbonclientextensions.http;
import io.netty.buffer.ByteBuf;
import io.reactivex.netty.protocol.http.client.HttpClientResponse;
import com.netflix.ribbonclientextensions.ResponseValidator;
public interface HttpResponseValidator extends ResponseValidator<HttpClientResponse<ByteBuf>> {
}
package com.netflix.ribbonclientextensions.http;
import java.util.Iterator;
import java.util.List;
import io.netty.buffer.ByteBuf;
import io.reactivex.netty.protocol.http.client.HttpClient;
import io.reactivex.netty.protocol.http.client.HttpClientRequest;
import io.reactivex.netty.protocol.http.client.HttpClientResponse;
import java.util.Iterator;
import rx.Observable;
import rx.functions.Func1;
import com.netflix.hystrix.HystrixObservableCommand;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
import com.netflix.hystrix.exception.*;
import com.netflix.hystrix.exception.HystrixBadRequestException;
import com.netflix.ribbonclientextensions.CacheProvider;
import com.netflix.ribbonclientextensions.ServerError;
import com.netflix.ribbonclientextensions.UnsuccessfulResponseException;
import com.netflix.ribbonclientextensions.http.HttpRequestTemplate.CacheProviderWithKeyTemplate;
import com.netflix.ribbonclientextensions.hystrix.FallbackHandler;
import com.netflix.ribbonclientextensions.template.TemplateParser;
import com.netflix.ribbonclientextensions.template.TemplateParsingException;
class RibbonHystrixObservableCommand<T> extends HystrixObservableCommand<T> {
......@@ -36,7 +38,16 @@ class RibbonHystrixObservableCommand<T> extends HystrixObservableCommand<T> {
@Override
protected String getCacheKey() {
return requestBuilder.cacheKey();
try {
String key = requestBuilder.cacheKey();
if (key == null) {
return super.getCacheKey();
} else {
return key;
}
} catch (TemplateParsingException e) {
return super.getCacheKey();
}
}
@Override
......@@ -51,14 +62,19 @@ class RibbonHystrixObservableCommand<T> extends HystrixObservableCommand<T> {
@Override
protected Observable<T> run() {
final String cacheKey = requestBuilder.cacheKey();
final Iterator<CacheProvider<T>> cacheProviders = requestTemplate.cacheProviders().iterator();
final Iterator<CacheProviderWithKeyTemplate<T>> cacheProviders = requestTemplate.cacheProviders().iterator();
Observable<T> cached = null;
if (cacheProviders.hasNext()) {
CacheProvider<T> provider = cacheProviders.next();
cached = provider.get(cacheKey, requestBuilder.requestProperties());
CacheProviderWithKeyTemplate<T> provider = cacheProviders.next();
String cacheKey;
try {
cacheKey = TemplateParser.toData(requestBuilder.requestProperties(), provider.getKeyTemplate());
} catch (TemplateParsingException e) {
return Observable.error(e);
}
cached = provider.getProvider().get(cacheKey, requestBuilder.requestProperties());
while (cacheProviders.hasNext()) {
final Observable<T> nextCache = cacheProviders.next().get(cacheKey, requestBuilder.requestProperties());
final Observable<T> nextCache = cacheProviders.next().getProvider().get(cacheKey, requestBuilder.requestProperties());
cached = cached.onErrorResumeNext(nextCache);
}
}
......
......@@ -46,6 +46,10 @@ public class TemplateParser {
return templateParts;
}
public static String toData(Map<String, Object> variables, ParsedTemplate parsedTemplate) throws TemplateParsingException {
return toData(variables, parsedTemplate.getTemplate(), parsedTemplate.getParsed());
}
public static String toData(Map<String, Object> variables, String template, List<Object> parsedList) throws TemplateParsingException {
int params = variables.size();
// skip expansion if there's no valid variables set. ex. {a} is the
......
......@@ -21,7 +21,6 @@ import rx.functions.Action0;
import rx.functions.Action1;
import rx.functions.Func1;
import com.google.common.collect.Lists;
import com.google.mockwebserver.MockResponse;
import com.google.mockwebserver.MockWebServer;
import com.netflix.hystrix.HystrixCommandGroupKey;
......@@ -29,9 +28,6 @@ import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.HystrixExecutableInfo;
import com.netflix.hystrix.HystrixObservableCommand;
import com.netflix.hystrix.exception.HystrixBadRequestException;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.LoadBalancerBuilder;
import com.netflix.loadbalancer.Server;
import com.netflix.ribbonclientextensions.http.HttpRequestTemplate;
import com.netflix.ribbonclientextensions.http.HttpResourceGroup;
import com.netflix.ribbonclientextensions.hystrix.FallbackHandler;
......@@ -50,7 +46,7 @@ public class RibbonTest {
HttpResourceGroup group = Ribbon.createHttpResourceGroup("myclient",
ClientOptions.create()
.withMaxAutoRetriesNextServer(3)
.useConfigurationBasedServerList("localhost:12345, localhost:10092, localhost:" + server.getPort()));
.withConfigurationBasedServerList("localhost:12345, localhost:10092, localhost:" + server.getPort()));
HttpRequestTemplate<ByteBuf> template = group.newRequestTemplate("test", ByteBuf.class);
RibbonRequest<ByteBuf> request = template.withUriTemplate("/").requestBuilder().build();
String result = request.execute().toString(Charset.defaultCharset());
......@@ -68,7 +64,7 @@ public class RibbonTest {
server.play();
HttpResourceGroup group = Ribbon.createHttpResourceGroup("myclient", ClientOptions.create()
.useConfigurationBasedServerList("localhost:" + server.getPort())
.withConfigurationBasedServerList("localhost:" + server.getPort())
.withMaxAutoRetriesNextServer(3));
HttpRequestTemplate<ByteBuf> template = group.newRequestTemplate("test");
......@@ -112,7 +108,7 @@ public class RibbonTest {
server.play();
HttpResourceGroup group = Ribbon.createHttpResourceGroup("myclient", ClientOptions.create()
.useConfigurationBasedServerList("localhost:" + server.getPort()));
.withConfigurationBasedServerList("localhost:" + server.getPort()));
HttpRequestTemplate<ByteBuf> template = group.newRequestTemplate("test", ByteBuf.class);
......@@ -150,7 +146,7 @@ public class RibbonTest {
@Test
public void testFallback() throws IOException {
HttpResourceGroup group = Ribbon.createHttpResourceGroup("myclient", ClientOptions.create()
.useConfigurationBasedServerList("localhost:12345")
.withConfigurationBasedServerList("localhost:12345")
.withMaxAutoRetriesNextServer(1));
HttpRequestTemplate<ByteBuf> template = group.newRequestTemplate("test", ByteBuf.class);
final String fallback = "fallback";
......@@ -194,7 +190,7 @@ public class RibbonTest {
@Test
public void testCacheHit() {
HttpResourceGroup group = Ribbon.createHttpResourceGroup("myclient", ClientOptions.create()
.useConfigurationBasedServerList("localhost:12345")
.withConfigurationBasedServerList("localhost:12345")
.withMaxAutoRetriesNextServer(1));
HttpRequestTemplate<ByteBuf> template = group.newRequestTemplate("test");
final String content = "from cache";
......@@ -238,7 +234,7 @@ public class RibbonTest {
server.play();
HttpResourceGroup group = Ribbon.createHttpResourceGroup("myclient", ClientOptions.create()
.useConfigurationBasedServerList("localhost:" + server.getPort())
.withConfigurationBasedServerList("localhost:" + server.getPort())
.withMaxAutoRetriesNextServer(1));
HttpRequestTemplate<ByteBuf> template = group.newRequestTemplate("test");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册