Merge branch 'master' into 2.0.x
# Conflicts: # spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/metrics/DefaultMetricsTagProvider.java # spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/rx/DeferredResultSubscriber.java # spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/rx/ResponseBodyEmitterSubscriber.java # spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/rx/RxResponse.java # spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/support/RibbonCommandContextTest.java # spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/rx/ObservableReturnValueHandlerTests.java # spring-cloud-netflix-dependencies/pom.xml
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -40,9 +40,9 @@ public interface AnnotatedParameterProcessor {
|
||||
/**
|
||||
* Process the annotated parameter.
|
||||
*
|
||||
* @param context the parameter context
|
||||
* @param context the parameter context
|
||||
* @param annotation the annotation instance
|
||||
* @param method the method that contains the annotation
|
||||
* @param method the method that contains the annotation
|
||||
* @return whether the parameter is http
|
||||
*/
|
||||
boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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,37 +27,37 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public abstract class BaseRequestInterceptor implements RequestInterceptor {
|
||||
|
||||
/**
|
||||
* The encoding properties.
|
||||
*/
|
||||
private final FeignClientEncodingProperties properties;
|
||||
/**
|
||||
* The encoding properties.
|
||||
*/
|
||||
private final FeignClientEncodingProperties properties;
|
||||
|
||||
/**
|
||||
* Creates new instance of {@link BaseRequestInterceptor}.
|
||||
*
|
||||
* @param properties the encoding properties
|
||||
*/
|
||||
protected BaseRequestInterceptor(FeignClientEncodingProperties properties) {
|
||||
Assert.notNull(properties, "Properties can not be null");
|
||||
this.properties = properties;
|
||||
}
|
||||
/**
|
||||
* Creates new instance of {@link BaseRequestInterceptor}.
|
||||
*
|
||||
* @param properties the encoding properties
|
||||
*/
|
||||
protected BaseRequestInterceptor(FeignClientEncodingProperties properties) {
|
||||
Assert.notNull(properties, "Properties can not be null");
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the header if it wasn't yet specified.
|
||||
*
|
||||
* @param requestTemplate the request
|
||||
* @param name the header name
|
||||
* @param values the header values
|
||||
*/
|
||||
protected void addHeader(RequestTemplate requestTemplate, String name, String... values) {
|
||||
/**
|
||||
* Adds the header if it wasn't yet specified.
|
||||
*
|
||||
* @param requestTemplate the request
|
||||
* @param name the header name
|
||||
* @param values the header values
|
||||
*/
|
||||
protected void addHeader(RequestTemplate requestTemplate, String name, String... values) {
|
||||
|
||||
if (!requestTemplate.headers().containsKey(name)) {
|
||||
requestTemplate.header(name, values);
|
||||
}
|
||||
}
|
||||
if (!requestTemplate.headers().containsKey(name)) {
|
||||
requestTemplate.header(name, values);
|
||||
}
|
||||
}
|
||||
|
||||
protected FeignClientEncodingProperties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
protected FeignClientEncodingProperties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -42,8 +42,8 @@ import org.springframework.context.annotation.Configuration;
|
||||
@AutoConfigureAfter(FeignAutoConfiguration.class)
|
||||
public class FeignAcceptGzipEncodingAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public FeignAcceptGzipEncodingInterceptor feignAcceptGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
|
||||
return new FeignAcceptGzipEncodingInterceptor(properties);
|
||||
}
|
||||
@Bean
|
||||
public FeignAcceptGzipEncodingInterceptor feignAcceptGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
|
||||
return new FeignAcceptGzipEncodingInterceptor(properties);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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,22 +28,22 @@ import feign.RequestTemplate;
|
||||
*/
|
||||
public class FeignAcceptGzipEncodingInterceptor extends BaseRequestInterceptor {
|
||||
|
||||
/**
|
||||
* Creates new instance of {@link FeignAcceptGzipEncodingInterceptor}.
|
||||
*
|
||||
* @param properties the encoding properties
|
||||
*/
|
||||
protected FeignAcceptGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
|
||||
super(properties);
|
||||
}
|
||||
/**
|
||||
* Creates new instance of {@link FeignAcceptGzipEncodingInterceptor}.
|
||||
*
|
||||
* @param properties the encoding properties
|
||||
*/
|
||||
protected FeignAcceptGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
|
||||
addHeader(template, HttpEncoding.ACCEPT_ENCODING_HEADER, HttpEncoding.GZIP_ENCODING,
|
||||
HttpEncoding.DEFLATE_ENCODING);
|
||||
}
|
||||
addHeader(template, HttpEncoding.ACCEPT_ENCODING_HEADER, HttpEncoding.GZIP_ENCODING,
|
||||
HttpEncoding.DEFLATE_ENCODING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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,52 +29,52 @@ import java.util.Objects;
|
||||
@ConfigurationProperties("feign.compression.request")
|
||||
public class FeignClientEncodingProperties {
|
||||
|
||||
/**
|
||||
* The list of supported mime types.
|
||||
*/
|
||||
private String[] mimeTypes = new String[]{"text/xml", "application/xml", "application/json"};
|
||||
/**
|
||||
* The list of supported mime types.
|
||||
*/
|
||||
private String[] mimeTypes = new String[]{"text/xml", "application/xml", "application/json"};
|
||||
|
||||
/**
|
||||
* The minimum threshold content size.
|
||||
*/
|
||||
private int minRequestSize = 2048;
|
||||
/**
|
||||
* The minimum threshold content size.
|
||||
*/
|
||||
private int minRequestSize = 2048;
|
||||
|
||||
public String[] getMimeTypes() {
|
||||
return mimeTypes;
|
||||
}
|
||||
public String[] getMimeTypes() {
|
||||
return mimeTypes;
|
||||
}
|
||||
|
||||
public void setMimeTypes(String[] mimeTypes) {
|
||||
this.mimeTypes = mimeTypes;
|
||||
}
|
||||
public void setMimeTypes(String[] mimeTypes) {
|
||||
this.mimeTypes = mimeTypes;
|
||||
}
|
||||
|
||||
public int getMinRequestSize() {
|
||||
return minRequestSize;
|
||||
}
|
||||
public int getMinRequestSize() {
|
||||
return minRequestSize;
|
||||
}
|
||||
|
||||
public void setMinRequestSize(int minRequestSize) {
|
||||
this.minRequestSize = minRequestSize;
|
||||
}
|
||||
public void setMinRequestSize(int minRequestSize) {
|
||||
this.minRequestSize = minRequestSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
FeignClientEncodingProperties that = (FeignClientEncodingProperties) o;
|
||||
return Arrays.equals(mimeTypes, that.mimeTypes) &&
|
||||
Objects.equals(minRequestSize, that.minRequestSize);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
FeignClientEncodingProperties that = (FeignClientEncodingProperties) o;
|
||||
return Arrays.equals(mimeTypes, that.mimeTypes) &&
|
||||
Objects.equals(minRequestSize, that.minRequestSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mimeTypes, minRequestSize);
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mimeTypes, minRequestSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("FeignClientEncodingProperties{")
|
||||
.append("mimeTypes=").append(Arrays.toString(mimeTypes)).append(", ")
|
||||
.append("minRequestSize=").append(minRequestSize)
|
||||
.append("}").toString();
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("FeignClientEncodingProperties{")
|
||||
.append("mimeTypes=").append(Arrays.toString(mimeTypes)).append(", ")
|
||||
.append("minRequestSize=").append(minRequestSize)
|
||||
.append("}").toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -42,8 +42,8 @@ import org.springframework.context.annotation.Configuration;
|
||||
@AutoConfigureAfter(FeignAutoConfiguration.class)
|
||||
public class FeignContentGzipEncodingAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public FeignContentGzipEncodingInterceptor feignContentGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
|
||||
return new FeignContentGzipEncodingInterceptor(properties);
|
||||
}
|
||||
@Bean
|
||||
public FeignContentGzipEncodingInterceptor feignContentGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
|
||||
return new FeignContentGzipEncodingInterceptor(properties);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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,84 +28,84 @@ import java.util.Map;
|
||||
*/
|
||||
public class FeignContentGzipEncodingInterceptor extends BaseRequestInterceptor {
|
||||
|
||||
/**
|
||||
* Creates new instance of {@link FeignContentGzipEncodingInterceptor}.
|
||||
*
|
||||
* @param properties the encoding properties
|
||||
*/
|
||||
protected FeignContentGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
|
||||
super(properties);
|
||||
}
|
||||
/**
|
||||
* Creates new instance of {@link FeignContentGzipEncodingInterceptor}.
|
||||
*
|
||||
* @param properties the encoding properties
|
||||
*/
|
||||
protected FeignContentGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
|
||||
if (requiresCompression(template)) {
|
||||
addHeader(template, HttpEncoding.CONTENT_ENCODING_HEADER, HttpEncoding.GZIP_ENCODING,
|
||||
HttpEncoding.DEFLATE_ENCODING);
|
||||
}
|
||||
}
|
||||
if (requiresCompression(template)) {
|
||||
addHeader(template, HttpEncoding.CONTENT_ENCODING_HEADER, HttpEncoding.GZIP_ENCODING,
|
||||
HttpEncoding.DEFLATE_ENCODING);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the request requires GZIP compression.
|
||||
*
|
||||
* @param template the request template
|
||||
* @return true if request requires compression, false otherwise
|
||||
*/
|
||||
private boolean requiresCompression(RequestTemplate template) {
|
||||
/**
|
||||
* Returns whether the request requires GZIP compression.
|
||||
*
|
||||
* @param template the request template
|
||||
* @return true if request requires compression, false otherwise
|
||||
*/
|
||||
private boolean requiresCompression(RequestTemplate template) {
|
||||
|
||||
final Map<String, Collection<String>> headers = template.headers();
|
||||
return matchesMimeType(headers.get(HttpEncoding.CONTENT_TYPE))
|
||||
&& contentLengthExceedThreshold(headers.get(HttpEncoding.CONTENT_LENGTH));
|
||||
}
|
||||
final Map<String, Collection<String>> headers = template.headers();
|
||||
return matchesMimeType(headers.get(HttpEncoding.CONTENT_TYPE))
|
||||
&& contentLengthExceedThreshold(headers.get(HttpEncoding.CONTENT_LENGTH));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the request content length exceed configured minimum size.
|
||||
*
|
||||
* @param contentLength the content length header value
|
||||
* @return true if length is grater than minimum size, false otherwise
|
||||
*/
|
||||
private boolean contentLengthExceedThreshold(Collection<String> contentLength) {
|
||||
/**
|
||||
* Returns whether the request content length exceed configured minimum size.
|
||||
*
|
||||
* @param contentLength the content length header value
|
||||
* @return true if length is grater than minimum size, false otherwise
|
||||
*/
|
||||
private boolean contentLengthExceedThreshold(Collection<String> contentLength) {
|
||||
|
||||
try {
|
||||
if (contentLength == null || contentLength.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (contentLength == null || contentLength.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final String strLen = contentLength.iterator().next();
|
||||
final long length = Long.parseLong(strLen);
|
||||
return length > getProperties().getMinRequestSize();
|
||||
} catch (NumberFormatException ex) {
|
||||
// ignores the exception
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final String strLen = contentLength.iterator().next();
|
||||
final long length = Long.parseLong(strLen);
|
||||
return length > getProperties().getMinRequestSize();
|
||||
} catch (NumberFormatException ex) {
|
||||
// ignores the exception
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the content mime types matches the configures mime types.
|
||||
*
|
||||
* @param contentTypes the content types
|
||||
* @return true if any specified content type matches the request content types
|
||||
*/
|
||||
private boolean matchesMimeType(Collection<String> contentTypes) {
|
||||
if (contentTypes == null || contentTypes.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Returns whether the content mime types matches the configures mime types.
|
||||
*
|
||||
* @param contentTypes the content types
|
||||
* @return true if any specified content type matches the request content types
|
||||
*/
|
||||
private boolean matchesMimeType(Collection<String> contentTypes) {
|
||||
if (contentTypes == null || contentTypes.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getProperties().getMimeTypes() == null || getProperties().getMimeTypes().length == 0) {
|
||||
// no specific mime types has been set - matching everything
|
||||
return true;
|
||||
}
|
||||
if (getProperties().getMimeTypes() == null || getProperties().getMimeTypes().length == 0) {
|
||||
// no specific mime types has been set - matching everything
|
||||
return true;
|
||||
}
|
||||
|
||||
for (String mimeType : getProperties().getMimeTypes()) {
|
||||
if (contentTypes.contains(mimeType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (String mimeType : getProperties().getMimeTypes()) {
|
||||
if (contentTypes.contains(mimeType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -23,33 +23,33 @@ package org.springframework.cloud.netflix.feign.encoding;
|
||||
*/
|
||||
public interface HttpEncoding {
|
||||
|
||||
/**
|
||||
* The HTTP Content-Length header.
|
||||
*/
|
||||
String CONTENT_LENGTH = "Content-Length";
|
||||
/**
|
||||
* The HTTP Content-Length header.
|
||||
*/
|
||||
String CONTENT_LENGTH = "Content-Length";
|
||||
|
||||
/**
|
||||
* The HTTP Content-Type header.
|
||||
*/
|
||||
String CONTENT_TYPE = "Content-Type";
|
||||
/**
|
||||
* The HTTP Content-Type header.
|
||||
*/
|
||||
String CONTENT_TYPE = "Content-Type";
|
||||
|
||||
/**
|
||||
* The HTTP Accept-Encoding header.
|
||||
*/
|
||||
String ACCEPT_ENCODING_HEADER = "Accept-Encoding";
|
||||
/**
|
||||
* The HTTP Accept-Encoding header.
|
||||
*/
|
||||
String ACCEPT_ENCODING_HEADER = "Accept-Encoding";
|
||||
|
||||
/**
|
||||
* The HTTP Content-Encoding header.
|
||||
*/
|
||||
String CONTENT_ENCODING_HEADER = "Content-Encoding";
|
||||
/**
|
||||
* The HTTP Content-Encoding header.
|
||||
*/
|
||||
String CONTENT_ENCODING_HEADER = "Content-Encoding";
|
||||
|
||||
/**
|
||||
* The GZIP encoding.
|
||||
*/
|
||||
String GZIP_ENCODING = "gzip";
|
||||
/**
|
||||
* The GZIP encoding.
|
||||
*/
|
||||
String GZIP_ENCODING = "gzip";
|
||||
|
||||
/**
|
||||
* The Deflate encoding.
|
||||
*/
|
||||
String DEFLATE_ENCODING = "deflate";
|
||||
/**
|
||||
* The Deflate encoding.
|
||||
*/
|
||||
String DEFLATE_ENCODING = "deflate";
|
||||
}
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
*
|
||||
* * Copyright 2013-2016 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.
|
||||
* 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;
|
||||
@@ -36,88 +34,88 @@ import java.util.List;
|
||||
*/
|
||||
public class RibbonLoadBalancedRetryPolicy implements LoadBalancedRetryPolicy {
|
||||
|
||||
public static final IClientConfigKey<String> RETRYABLE_STATUS_CODES = new CommonClientConfigKey<String>("retryableStatusCodes") {};
|
||||
private int sameServerCount = 0;
|
||||
private int nextServerCount = 0;
|
||||
private String serviceId;
|
||||
private RibbonLoadBalancerContext lbContext;
|
||||
private ServiceInstanceChooser loadBalanceChooser;
|
||||
List<Integer> retryableStatusCodes = new ArrayList<>();
|
||||
public static final IClientConfigKey<String> RETRYABLE_STATUS_CODES = new CommonClientConfigKey<String>("retryableStatusCodes") {};
|
||||
private int sameServerCount = 0;
|
||||
private int nextServerCount = 0;
|
||||
private String serviceId;
|
||||
private RibbonLoadBalancerContext lbContext;
|
||||
private ServiceInstanceChooser loadBalanceChooser;
|
||||
List<Integer> retryableStatusCodes = new ArrayList<>();
|
||||
|
||||
public RibbonLoadBalancedRetryPolicy(String serviceId, RibbonLoadBalancerContext context, ServiceInstanceChooser loadBalanceChooser) {
|
||||
this.serviceId = serviceId;
|
||||
this.lbContext = context;
|
||||
this.loadBalanceChooser = loadBalanceChooser;
|
||||
}
|
||||
public RibbonLoadBalancedRetryPolicy(String serviceId, RibbonLoadBalancerContext context, ServiceInstanceChooser loadBalanceChooser) {
|
||||
this.serviceId = serviceId;
|
||||
this.lbContext = context;
|
||||
this.loadBalanceChooser = loadBalanceChooser;
|
||||
}
|
||||
|
||||
public RibbonLoadBalancedRetryPolicy(String serviceId, RibbonLoadBalancerContext context, ServiceInstanceChooser loadBalanceChooser,
|
||||
IClientConfig clientConfig) {
|
||||
this.serviceId = serviceId;
|
||||
this.lbContext = context;
|
||||
this.loadBalanceChooser = loadBalanceChooser;
|
||||
String retryableStatusCodesProp = clientConfig.getPropertyAsString(RETRYABLE_STATUS_CODES, "");
|
||||
String[] retryableStatusCodesArray = retryableStatusCodesProp.split(",");
|
||||
for(String code : retryableStatusCodesArray) {
|
||||
if(!StringUtils.isEmpty(code)) {
|
||||
try {
|
||||
retryableStatusCodes.add(Integer.valueOf(code.trim()));
|
||||
} catch (NumberFormatException e) {
|
||||
//TODO log
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public RibbonLoadBalancedRetryPolicy(String serviceId, RibbonLoadBalancerContext context, ServiceInstanceChooser loadBalanceChooser,
|
||||
IClientConfig clientConfig) {
|
||||
this.serviceId = serviceId;
|
||||
this.lbContext = context;
|
||||
this.loadBalanceChooser = loadBalanceChooser;
|
||||
String retryableStatusCodesProp = clientConfig.getPropertyAsString(RETRYABLE_STATUS_CODES, "");
|
||||
String[] retryableStatusCodesArray = retryableStatusCodesProp.split(",");
|
||||
for(String code : retryableStatusCodesArray) {
|
||||
if(!StringUtils.isEmpty(code)) {
|
||||
try {
|
||||
retryableStatusCodes.add(Integer.valueOf(code.trim()));
|
||||
} catch (NumberFormatException e) {
|
||||
//TODO log
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canRetry(LoadBalancedRetryContext context) {
|
||||
HttpMethod method = context.getRequest().getMethod();
|
||||
return HttpMethod.GET == method || lbContext.isOkToRetryOnAllOperations();
|
||||
}
|
||||
public boolean canRetry(LoadBalancedRetryContext context) {
|
||||
HttpMethod method = context.getRequest().getMethod();
|
||||
return HttpMethod.GET == method || lbContext.isOkToRetryOnAllOperations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRetrySameServer(LoadBalancedRetryContext context) {
|
||||
return sameServerCount < lbContext.getRetryHandler().getMaxRetriesOnSameServer() && canRetry(context);
|
||||
}
|
||||
@Override
|
||||
public boolean canRetrySameServer(LoadBalancedRetryContext context) {
|
||||
return sameServerCount < lbContext.getRetryHandler().getMaxRetriesOnSameServer() && canRetry(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRetryNextServer(LoadBalancedRetryContext context) {
|
||||
//this will be called after a failure occurs and we increment the counter
|
||||
//so we check that the count is less than or equals to too make sure
|
||||
//we try the next server the right number of times
|
||||
return nextServerCount <= lbContext.getRetryHandler().getMaxRetriesOnNextServer() && canRetry(context);
|
||||
}
|
||||
@Override
|
||||
public boolean canRetryNextServer(LoadBalancedRetryContext context) {
|
||||
//this will be called after a failure occurs and we increment the counter
|
||||
//so we check that the count is less than or equals to too make sure
|
||||
//we try the next server the right number of times
|
||||
return nextServerCount <= lbContext.getRetryHandler().getMaxRetriesOnNextServer() && canRetry(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(LoadBalancedRetryContext context) {
|
||||
@Override
|
||||
public void close(LoadBalancedRetryContext context) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerThrowable(LoadBalancedRetryContext context, Throwable throwable) {
|
||||
//Check if we need to ask the load balancer for a new server.
|
||||
//Do this before we increment the counters because the first call to this method
|
||||
//is not a retry it is just an initial failure.
|
||||
if(!canRetrySameServer(context) && canRetryNextServer(context)) {
|
||||
context.setServiceInstance(loadBalanceChooser.choose(serviceId));
|
||||
}
|
||||
//This method is called regardless of whether we are retrying or making the first request.
|
||||
//Since we do not count the initial request in the retry count we don't reset the counter
|
||||
//until we actually equal the same server count limit. This will allow us to make the initial
|
||||
//request plus the right number of retries.
|
||||
if(sameServerCount >= lbContext.getRetryHandler().getMaxRetriesOnSameServer() && canRetry(context)) {
|
||||
//reset same server since we are moving to a new server
|
||||
sameServerCount = 0;
|
||||
nextServerCount++;
|
||||
if(!canRetryNextServer(context)) {
|
||||
context.setExhaustedOnly();
|
||||
}
|
||||
} else {
|
||||
sameServerCount++;
|
||||
}
|
||||
@Override
|
||||
public void registerThrowable(LoadBalancedRetryContext context, Throwable throwable) {
|
||||
//Check if we need to ask the load balancer for a new server.
|
||||
//Do this before we increment the counters because the first call to this method
|
||||
//is not a retry it is just an initial failure.
|
||||
if(!canRetrySameServer(context) && canRetryNextServer(context)) {
|
||||
context.setServiceInstance(loadBalanceChooser.choose(serviceId));
|
||||
}
|
||||
//This method is called regardless of whether we are retrying or making the first request.
|
||||
//Since we do not count the initial request in the retry count we don't reset the counter
|
||||
//until we actually equal the same server count limit. This will allow us to make the initial
|
||||
//request plus the right number of retries.
|
||||
if(sameServerCount >= lbContext.getRetryHandler().getMaxRetriesOnSameServer() && canRetry(context)) {
|
||||
//reset same server since we are moving to a new server
|
||||
sameServerCount = 0;
|
||||
nextServerCount++;
|
||||
if(!canRetryNextServer(context)) {
|
||||
context.setExhaustedOnly();
|
||||
}
|
||||
} else {
|
||||
sameServerCount++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retryableStatusCode(int statusCode) {
|
||||
return retryableStatusCodes.contains(statusCode);
|
||||
}
|
||||
@Override
|
||||
public boolean retryableStatusCode(int statusCode) {
|
||||
return retryableStatusCodes.contains(statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -24,17 +24,17 @@ import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser;
|
||||
*/
|
||||
public class RibbonLoadBalancedRetryPolicyFactory implements LoadBalancedRetryPolicyFactory {
|
||||
|
||||
private SpringClientFactory clientFactory;
|
||||
private SpringClientFactory clientFactory;
|
||||
|
||||
public RibbonLoadBalancedRetryPolicyFactory(SpringClientFactory clientFactory) {
|
||||
this.clientFactory = clientFactory;
|
||||
}
|
||||
public RibbonLoadBalancedRetryPolicyFactory(SpringClientFactory clientFactory) {
|
||||
this.clientFactory = clientFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoadBalancedRetryPolicy create(String serviceId, ServiceInstanceChooser loadBalanceChooser) {
|
||||
RibbonLoadBalancerContext lbContext = this.clientFactory
|
||||
.getLoadBalancerContext(serviceId);
|
||||
return new RibbonLoadBalancedRetryPolicy(serviceId, lbContext, loadBalanceChooser, clientFactory.getClientConfig(serviceId));
|
||||
}
|
||||
@Override
|
||||
public LoadBalancedRetryPolicy create(String serviceId, ServiceInstanceChooser loadBalanceChooser) {
|
||||
RibbonLoadBalancerContext lbContext = this.clientFactory
|
||||
.getLoadBalancerContext(serviceId);
|
||||
return new RibbonLoadBalancedRetryPolicy(serviceId, lbContext, loadBalanceChooser, clientFactory.getClientConfig(serviceId));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,33 +21,33 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ResettableServletInputStreamWrapper extends ServletInputStream {
|
||||
private final ByteArrayInputStream input;
|
||||
private final ByteArrayInputStream input;
|
||||
|
||||
public ResettableServletInputStreamWrapper(byte[] data) {
|
||||
this.input = new ByteArrayInputStream(data);
|
||||
}
|
||||
public ResettableServletInputStreamWrapper(byte[] data) {
|
||||
this.input = new ByteArrayInputStream(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean isFinished() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadListener(ReadListener listener) {
|
||||
}
|
||||
@Override
|
||||
public void setReadListener(ReadListener listener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return input.read();
|
||||
}
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return input.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void reset() throws IOException {
|
||||
input.reset();
|
||||
}
|
||||
@Override
|
||||
public synchronized void reset() throws IOException {
|
||||
input.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -30,14 +30,14 @@ import java.util.Locale;
|
||||
*/
|
||||
final class Invoices {
|
||||
|
||||
public static List<Invoice> createInvoiceList(int count) {
|
||||
final List<Invoice> invoices = new ArrayList<>();
|
||||
for (int ind = 0; ind < count; ind++) {
|
||||
final Invoice invoice = new Invoice();
|
||||
invoice.setTitle("Invoice " + (ind + 1));
|
||||
invoice.setAmount(new BigDecimal(String.format(Locale.US, "%.2f", Math.random() * 1000)));
|
||||
invoices.add(invoice);
|
||||
}
|
||||
return invoices;
|
||||
}
|
||||
public static List<Invoice> createInvoiceList(int count) {
|
||||
final List<Invoice> invoices = new ArrayList<>();
|
||||
for (int ind = 0; ind < count; ind++) {
|
||||
final Invoice invoice = new Invoice();
|
||||
invoice.setTitle("Invoice " + (ind + 1));
|
||||
invoice.setAmount(new BigDecimal(String.format(Locale.US, "%.2f", Math.random() * 1000)));
|
||||
invoices.add(invoice);
|
||||
}
|
||||
return invoices;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -25,23 +25,23 @@ import java.math.BigDecimal;
|
||||
*/
|
||||
public class Invoice {
|
||||
|
||||
private String title;
|
||||
private String title;
|
||||
|
||||
private BigDecimal amount;
|
||||
private BigDecimal amount;
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
public void setAmount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -37,27 +37,27 @@ import java.util.Locale;
|
||||
@RestController
|
||||
public class InvoiceResource {
|
||||
|
||||
@RequestMapping(value = "invoices", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ResponseEntity<List<Invoice>> getInvoices() {
|
||||
@RequestMapping(value = "invoices", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ResponseEntity<List<Invoice>> getInvoices() {
|
||||
|
||||
return ResponseEntity.ok(createInvoiceList(100));
|
||||
}
|
||||
return ResponseEntity.ok(createInvoiceList(100));
|
||||
}
|
||||
|
||||
@RequestMapping(value = "invoices", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
ResponseEntity<List<Invoice>> saveInvoices(@RequestBody List<Invoice> invoices) {
|
||||
@RequestMapping(value = "invoices", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
ResponseEntity<List<Invoice>> saveInvoices(@RequestBody List<Invoice> invoices) {
|
||||
|
||||
return ResponseEntity.ok(invoices);
|
||||
}
|
||||
return ResponseEntity.ok(invoices);
|
||||
}
|
||||
|
||||
private List<Invoice> createInvoiceList(int count) {
|
||||
final List<Invoice> invoices = new ArrayList<>();
|
||||
for (int ind = 0; ind < count; ind++) {
|
||||
final Invoice invoice = new Invoice();
|
||||
invoice.setTitle("Invoice " + (ind + 1));
|
||||
invoice.setAmount(new BigDecimal(String.format(Locale.US, "%.2f", Math.random() * 1000)));
|
||||
invoices.add(invoice);
|
||||
}
|
||||
return invoices;
|
||||
}
|
||||
private List<Invoice> createInvoiceList(int count) {
|
||||
final List<Invoice> invoices = new ArrayList<>();
|
||||
for (int ind = 0; ind < count; ind++) {
|
||||
final Invoice invoice = new Invoice();
|
||||
invoice.setTitle("Invoice " + (ind + 1));
|
||||
invoice.setAmount(new BigDecimal(String.format(Locale.US, "%.2f", Math.random() * 1000)));
|
||||
invoices.add(invoice);
|
||||
}
|
||||
return invoices;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -54,7 +54,7 @@ import static org.junit.Assert.assertTrue;
|
||||
@SpringBootTest(classes = FeignRibbonClientRetryTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
|
||||
"spring.application.name=feignclientretrytest", "feign.okhttp.enabled=false",
|
||||
"feign.httpclient.enabled=false", "feign.hystrix.enabled=false", "localapp.ribbon.MaxAutoRetries=2",
|
||||
"localapp.ribbon.MaxAutoRetriesNextServer=3"})
|
||||
"localapp.ribbon.MaxAutoRetriesNextServer=3"})
|
||||
@DirtiesContext
|
||||
public class FeignRibbonClientRetryTests {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -99,7 +99,7 @@ import rx.Single;
|
||||
"spring.application.name=feignclienttest",
|
||||
"logging.level.org.springframework.cloud.netflix.feign.valid=DEBUG",
|
||||
"feign.httpclient.enabled=false", "feign.okhttp.enabled=false",
|
||||
"feign.hystrix.enabled=true"})
|
||||
"feign.hystrix.enabled=true"})
|
||||
@DirtiesContext
|
||||
public class FeignClientTests {
|
||||
|
||||
|
||||
@@ -59,19 +59,19 @@ public class RibbonClientPreprocessorOverridesIntegrationTests {
|
||||
@Test
|
||||
public void ruleOverridesToRandom() throws Exception {
|
||||
RandomRule.class.cast(getLoadBalancer("foo").getRule());
|
||||
RoundRobinRule.class.cast(getLoadBalancer("bar").getRule());
|
||||
RoundRobinRule.class.cast(getLoadBalancer("bar").getRule());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pingOverridesToDummy() throws Exception {
|
||||
DummyPing.class.cast(getLoadBalancer("foo").getPing());
|
||||
PingConstant.class.cast(getLoadBalancer("bar").getPing());
|
||||
PingConstant.class.cast(getLoadBalancer("bar").getPing());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serverListOverridesToMy() throws Exception {
|
||||
FooServiceList.class.cast(getLoadBalancer("foo").getServerListImpl());
|
||||
BarServiceList.class.cast(getLoadBalancer("bar").getServerListImpl());
|
||||
BarServiceList.class.cast(getLoadBalancer("bar").getServerListImpl());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -88,10 +88,10 @@ public class RibbonClientPreprocessorOverridesIntegrationTests {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@RibbonClients({
|
||||
@RibbonClient(name = "foo", configuration = FooConfiguration.class),
|
||||
@RibbonClient(name = "bar", configuration = BarConfiguration.class)
|
||||
})
|
||||
@RibbonClients({
|
||||
@RibbonClient(name = "foo", configuration = FooConfiguration.class),
|
||||
@RibbonClient(name = "bar", configuration = BarConfiguration.class)
|
||||
})
|
||||
@Import({ UtilAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
|
||||
ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class})
|
||||
protected static class TestConfiguration {
|
||||
@@ -128,35 +128,35 @@ public class RibbonClientPreprocessorOverridesIntegrationTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class BarConfiguration {
|
||||
@Configuration
|
||||
public static class BarConfiguration {
|
||||
|
||||
@Bean
|
||||
public IRule ribbonRule() {
|
||||
return new RoundRobinRule();
|
||||
}
|
||||
@Bean
|
||||
public IRule ribbonRule() {
|
||||
return new RoundRobinRule();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IPing ribbonPing() {
|
||||
return new PingConstant();
|
||||
}
|
||||
@Bean
|
||||
public IPing ribbonPing() {
|
||||
return new PingConstant();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ServerList<Server> ribbonServerList(IClientConfig config) {
|
||||
return new BarServiceList(config);
|
||||
}
|
||||
@Bean
|
||||
public ServerList<Server> ribbonServerList(IClientConfig config) {
|
||||
return new BarServiceList(config);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ZonePreferenceServerListFilter serverListFilter() {
|
||||
ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter();
|
||||
filter.setZone("BarTestZone");
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
@Bean
|
||||
public ZonePreferenceServerListFilter serverListFilter() {
|
||||
ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter();
|
||||
filter.setZone("BarTestZone");
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
|
||||
public static class BarServiceList extends ConfigurationBasedServerList {
|
||||
public BarServiceList(IClientConfig config) {
|
||||
super.initWithNiwsConfig(config);
|
||||
}
|
||||
}
|
||||
public static class BarServiceList extends ConfigurationBasedServerList {
|
||||
public BarServiceList(IClientConfig config) {
|
||||
super.initWithNiwsConfig(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2017 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;
|
||||
|
||||
import com.netflix.client.DefaultLoadBalancerRetryHandler;
|
||||
@@ -43,203 +59,203 @@ import static org.mockito.Mockito.verify;
|
||||
*/
|
||||
public class RibbonLoadBalancedRetryPolicyFactoryTests {
|
||||
|
||||
@Mock
|
||||
private SpringClientFactory clientFactory;
|
||||
@Mock
|
||||
private SpringClientFactory clientFactory;
|
||||
|
||||
@Mock
|
||||
private BaseLoadBalancer loadBalancer;
|
||||
@Mock
|
||||
private BaseLoadBalancer loadBalancer;
|
||||
|
||||
@Mock
|
||||
private LoadBalancerStats loadBalancerStats;
|
||||
@Mock
|
||||
private LoadBalancerStats loadBalancerStats;
|
||||
|
||||
@Mock
|
||||
private ServerStats serverStats;
|
||||
@Mock
|
||||
private ServerStats serverStats;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
given(this.clientFactory.getLoadBalancerContext(anyString())).willReturn(
|
||||
new RibbonLoadBalancerContext(this.loadBalancer));
|
||||
given(this.clientFactory.getInstance(anyString(), eq(ServerIntrospector.class)))
|
||||
.willReturn(new DefaultServerIntrospector() {
|
||||
@Override
|
||||
public Map<String, String> getMetadata(Server server) {
|
||||
return Collections.singletonMap("mykey", "myvalue");
|
||||
}
|
||||
});
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
given(this.clientFactory.getLoadBalancerContext(anyString())).willReturn(
|
||||
new RibbonLoadBalancerContext(this.loadBalancer));
|
||||
given(this.clientFactory.getInstance(anyString(), eq(ServerIntrospector.class)))
|
||||
.willReturn(new DefaultServerIntrospector() {
|
||||
@Override
|
||||
public Map<String, String> getMetadata(Server server) {
|
||||
return Collections.singletonMap("mykey", "myvalue");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {}
|
||||
@After
|
||||
public void tearDown() throws Exception {}
|
||||
|
||||
@Test
|
||||
public void testGetRetryPolicyNoRetry() throws Exception {
|
||||
int sameServer = 0;
|
||||
int nextServer = 0;
|
||||
boolean retryOnAllOps = false;
|
||||
RibbonServer server = getRibbonServer();
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(sameServer).when(config).getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(nextServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(nextServer).when(config).getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(retryOnAllOps).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean());
|
||||
doReturn(retryOnAllOps).when(config).getPropertyAsBoolean(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean());
|
||||
doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(server.getServiceId()).when(config).getClientName();
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId()));
|
||||
clientFactory.getLoadBalancerContext(server.getServiceId()).setRetryHandler(new DefaultLoadBalancerRetryHandler(config));
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
RibbonLoadBalancedRetryPolicyFactory factory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
LoadBalancedRetryPolicy policy = factory.create(server.getServiceId(), client);
|
||||
HttpRequest request = mock(HttpRequest.class);
|
||||
doReturn(HttpMethod.GET).when(request).getMethod();
|
||||
LoadBalancedRetryContext context = new LoadBalancedRetryContext(null, request);
|
||||
assertThat(policy.canRetryNextServer(context), is(true));
|
||||
assertThat(policy.canRetrySameServer(context), is(false));
|
||||
assertThat(policy.retryableStatusCode(400), is(false));
|
||||
}
|
||||
@Test
|
||||
public void testGetRetryPolicyNoRetry() throws Exception {
|
||||
int sameServer = 0;
|
||||
int nextServer = 0;
|
||||
boolean retryOnAllOps = false;
|
||||
RibbonServer server = getRibbonServer();
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(sameServer).when(config).getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(nextServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(nextServer).when(config).getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(retryOnAllOps).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean());
|
||||
doReturn(retryOnAllOps).when(config).getPropertyAsBoolean(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean());
|
||||
doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(server.getServiceId()).when(config).getClientName();
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId()));
|
||||
clientFactory.getLoadBalancerContext(server.getServiceId()).setRetryHandler(new DefaultLoadBalancerRetryHandler(config));
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
RibbonLoadBalancedRetryPolicyFactory factory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
LoadBalancedRetryPolicy policy = factory.create(server.getServiceId(), client);
|
||||
HttpRequest request = mock(HttpRequest.class);
|
||||
doReturn(HttpMethod.GET).when(request).getMethod();
|
||||
LoadBalancedRetryContext context = new LoadBalancedRetryContext(null, request);
|
||||
assertThat(policy.canRetryNextServer(context), is(true));
|
||||
assertThat(policy.canRetrySameServer(context), is(false));
|
||||
assertThat(policy.retryableStatusCode(400), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRetryPolicyNotGet() throws Exception {
|
||||
int sameServer = 3;
|
||||
int nextServer = 3;
|
||||
boolean retryOnAllOps = false;
|
||||
RibbonServer server = getRibbonServer();
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(sameServer).when(config).getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(nextServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(nextServer).when(config).getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(retryOnAllOps).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean());
|
||||
doReturn(retryOnAllOps).when(config).getPropertyAsBoolean(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean());
|
||||
doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(server.getServiceId()).when(config).getClientName();
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId()));
|
||||
clientFactory.getLoadBalancerContext(server.getServiceId()).setRetryHandler(new DefaultLoadBalancerRetryHandler(config));
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
RibbonLoadBalancedRetryPolicyFactory factory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
LoadBalancedRetryPolicy policy = factory.create(server.getServiceId(), client);
|
||||
HttpRequest request = mock(HttpRequest.class);
|
||||
doReturn(HttpMethod.POST).when(request).getMethod();
|
||||
LoadBalancedRetryContext context = new LoadBalancedRetryContext(null, request);
|
||||
assertThat(policy.canRetryNextServer(context), is(false));
|
||||
assertThat(policy.canRetrySameServer(context), is(false));
|
||||
assertThat(policy.retryableStatusCode(400), is(false));
|
||||
}
|
||||
@Test
|
||||
public void testGetRetryPolicyNotGet() throws Exception {
|
||||
int sameServer = 3;
|
||||
int nextServer = 3;
|
||||
boolean retryOnAllOps = false;
|
||||
RibbonServer server = getRibbonServer();
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(sameServer).when(config).getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(nextServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(nextServer).when(config).getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(retryOnAllOps).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean());
|
||||
doReturn(retryOnAllOps).when(config).getPropertyAsBoolean(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean());
|
||||
doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(server.getServiceId()).when(config).getClientName();
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId()));
|
||||
clientFactory.getLoadBalancerContext(server.getServiceId()).setRetryHandler(new DefaultLoadBalancerRetryHandler(config));
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
RibbonLoadBalancedRetryPolicyFactory factory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
LoadBalancedRetryPolicy policy = factory.create(server.getServiceId(), client);
|
||||
HttpRequest request = mock(HttpRequest.class);
|
||||
doReturn(HttpMethod.POST).when(request).getMethod();
|
||||
LoadBalancedRetryContext context = new LoadBalancedRetryContext(null, request);
|
||||
assertThat(policy.canRetryNextServer(context), is(false));
|
||||
assertThat(policy.canRetrySameServer(context), is(false));
|
||||
assertThat(policy.retryableStatusCode(400), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRetryPolicyRetryOnNonGet() throws Exception {
|
||||
int sameServer = 3;
|
||||
int nextServer = 3;
|
||||
boolean retryOnAllOps = true;
|
||||
RibbonServer server = getRibbonServer();
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(sameServer).when(config).getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(nextServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(nextServer).when(config).getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(retryOnAllOps).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean());
|
||||
doReturn(retryOnAllOps).when(config).getPropertyAsBoolean(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean());
|
||||
doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(server.getServiceId()).when(config).getClientName();
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId()));
|
||||
clientFactory.getLoadBalancerContext(server.getServiceId()).initWithNiwsConfig(config);
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
RibbonLoadBalancedRetryPolicyFactory factory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
LoadBalancedRetryPolicy policy = factory.create(server.getServiceId(), client);
|
||||
HttpRequest request = mock(HttpRequest.class);
|
||||
doReturn(HttpMethod.POST).when(request).getMethod();
|
||||
LoadBalancedRetryContext context = new LoadBalancedRetryContext(null, request);
|
||||
assertThat(policy.canRetryNextServer(context), is(true));
|
||||
assertThat(policy.canRetrySameServer(context), is(true));
|
||||
assertThat(policy.retryableStatusCode(400), is(false));
|
||||
}
|
||||
@Test
|
||||
public void testGetRetryPolicyRetryOnNonGet() throws Exception {
|
||||
int sameServer = 3;
|
||||
int nextServer = 3;
|
||||
boolean retryOnAllOps = true;
|
||||
RibbonServer server = getRibbonServer();
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(sameServer).when(config).getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(nextServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(nextServer).when(config).getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(retryOnAllOps).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean());
|
||||
doReturn(retryOnAllOps).when(config).getPropertyAsBoolean(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean());
|
||||
doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(server.getServiceId()).when(config).getClientName();
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId()));
|
||||
clientFactory.getLoadBalancerContext(server.getServiceId()).initWithNiwsConfig(config);
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
RibbonLoadBalancedRetryPolicyFactory factory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
LoadBalancedRetryPolicy policy = factory.create(server.getServiceId(), client);
|
||||
HttpRequest request = mock(HttpRequest.class);
|
||||
doReturn(HttpMethod.POST).when(request).getMethod();
|
||||
LoadBalancedRetryContext context = new LoadBalancedRetryContext(null, request);
|
||||
assertThat(policy.canRetryNextServer(context), is(true));
|
||||
assertThat(policy.canRetrySameServer(context), is(true));
|
||||
assertThat(policy.retryableStatusCode(400), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRetryPolicyRetryCount() throws Exception {
|
||||
int sameServer = 3;
|
||||
int nextServer = 3;
|
||||
RibbonServer server = getRibbonServer();
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(nextServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(false).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId()));
|
||||
doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
clientFactory.getLoadBalancerContext(server.getServiceId()).setRetryHandler(new DefaultLoadBalancerRetryHandler(config));
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
RibbonLoadBalancedRetryPolicyFactory factory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
LoadBalancedRetryPolicy policy = factory.create(server.getServiceId(), client);
|
||||
HttpRequest request = mock(HttpRequest.class);
|
||||
doReturn(HttpMethod.GET).when(request).getMethod();
|
||||
LoadBalancedRetryContext context = spy(new LoadBalancedRetryContext(null, request));
|
||||
//Loop through as if we are retrying a request until we exhaust the number of retries
|
||||
//outer loop is for next server retries
|
||||
//inner loop is for same server retries
|
||||
for(int i = 0; i < nextServer + 1; i++) {
|
||||
//iterate once time beyond the same server retry limit to cause us to reset
|
||||
//the same sever counter and increment the next server counter
|
||||
for(int j = 0; j < sameServer + 1; j++) {
|
||||
if(j < 3) {
|
||||
assertThat(policy.canRetrySameServer(context), is(true));
|
||||
} else {
|
||||
assertThat(policy.canRetrySameServer(context), is(false));
|
||||
}
|
||||
policy.registerThrowable(context, new IOException());
|
||||
}
|
||||
if(i < 3) {
|
||||
assertThat(policy.canRetryNextServer(context), is(true));
|
||||
} else {
|
||||
assertThat(policy.canRetryNextServer(context), is(false));
|
||||
}
|
||||
}
|
||||
assertThat(context.isExhaustedOnly(), is(true));
|
||||
assertThat(policy.retryableStatusCode(400), is(false));
|
||||
verify(context, times(4)).setServiceInstance(any(ServiceInstance.class));
|
||||
}
|
||||
@Test
|
||||
public void testGetRetryPolicyRetryCount() throws Exception {
|
||||
int sameServer = 3;
|
||||
int nextServer = 3;
|
||||
RibbonServer server = getRibbonServer();
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(nextServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(false).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId()));
|
||||
doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
clientFactory.getLoadBalancerContext(server.getServiceId()).setRetryHandler(new DefaultLoadBalancerRetryHandler(config));
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
RibbonLoadBalancedRetryPolicyFactory factory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
LoadBalancedRetryPolicy policy = factory.create(server.getServiceId(), client);
|
||||
HttpRequest request = mock(HttpRequest.class);
|
||||
doReturn(HttpMethod.GET).when(request).getMethod();
|
||||
LoadBalancedRetryContext context = spy(new LoadBalancedRetryContext(null, request));
|
||||
//Loop through as if we are retrying a request until we exhaust the number of retries
|
||||
//outer loop is for next server retries
|
||||
//inner loop is for same server retries
|
||||
for(int i = 0; i < nextServer + 1; i++) {
|
||||
//iterate once time beyond the same server retry limit to cause us to reset
|
||||
//the same sever counter and increment the next server counter
|
||||
for(int j = 0; j < sameServer + 1; j++) {
|
||||
if(j < 3) {
|
||||
assertThat(policy.canRetrySameServer(context), is(true));
|
||||
} else {
|
||||
assertThat(policy.canRetrySameServer(context), is(false));
|
||||
}
|
||||
policy.registerThrowable(context, new IOException());
|
||||
}
|
||||
if(i < 3) {
|
||||
assertThat(policy.canRetryNextServer(context), is(true));
|
||||
} else {
|
||||
assertThat(policy.canRetryNextServer(context), is(false));
|
||||
}
|
||||
}
|
||||
assertThat(context.isExhaustedOnly(), is(true));
|
||||
assertThat(policy.retryableStatusCode(400), is(false));
|
||||
verify(context, times(4)).setServiceInstance(any(ServiceInstance.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetryableStatusCodes() throws Exception {
|
||||
int sameServer = 3;
|
||||
int nextServer = 3;
|
||||
RibbonServer server = getRibbonServer();
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(nextServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(false).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId()));
|
||||
doReturn("404, 418,502,foo, ,").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
clientFactory.getLoadBalancerContext(server.getServiceId()).setRetryHandler(new DefaultLoadBalancerRetryHandler(config));
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
RibbonLoadBalancedRetryPolicyFactory factory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
LoadBalancedRetryPolicy policy = factory.create(server.getServiceId(), client);
|
||||
HttpRequest request = mock(HttpRequest.class);
|
||||
doReturn(HttpMethod.GET).when(request).getMethod();
|
||||
assertThat(policy.retryableStatusCode(400), is(false));
|
||||
assertThat(policy.retryableStatusCode(404), is(true));
|
||||
assertThat(policy.retryableStatusCode(418), is(true));
|
||||
assertThat(policy.retryableStatusCode(502), is(true));
|
||||
}
|
||||
@Test
|
||||
public void testRetryableStatusCodes() throws Exception {
|
||||
int sameServer = 3;
|
||||
int nextServer = 3;
|
||||
RibbonServer server = getRibbonServer();
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(nextServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(false).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId()));
|
||||
doReturn("404, 418,502,foo, ,").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
clientFactory.getLoadBalancerContext(server.getServiceId()).setRetryHandler(new DefaultLoadBalancerRetryHandler(config));
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
RibbonLoadBalancedRetryPolicyFactory factory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
LoadBalancedRetryPolicy policy = factory.create(server.getServiceId(), client);
|
||||
HttpRequest request = mock(HttpRequest.class);
|
||||
doReturn(HttpMethod.GET).when(request).getMethod();
|
||||
assertThat(policy.retryableStatusCode(400), is(false));
|
||||
assertThat(policy.retryableStatusCode(404), is(true));
|
||||
assertThat(policy.retryableStatusCode(418), is(true));
|
||||
assertThat(policy.retryableStatusCode(502), is(true));
|
||||
}
|
||||
|
||||
protected RibbonLoadBalancerClient getRibbonLoadBalancerClient(
|
||||
RibbonServer ribbonServer) {
|
||||
given(this.loadBalancer.getName()).willReturn(ribbonServer.getServiceId());
|
||||
given(this.loadBalancer.chooseServer(anyObject())).willReturn(
|
||||
ribbonServer.getServer());
|
||||
given(this.loadBalancer.getLoadBalancerStats())
|
||||
.willReturn(this.loadBalancerStats);
|
||||
given(this.loadBalancerStats.getSingleServerStat(ribbonServer.getServer()))
|
||||
.willReturn(this.serverStats);
|
||||
given(this.clientFactory.getLoadBalancer(this.loadBalancer.getName()))
|
||||
.willReturn(this.loadBalancer);
|
||||
return new RibbonLoadBalancerClient(this.clientFactory);
|
||||
}
|
||||
protected RibbonLoadBalancerClient getRibbonLoadBalancerClient(
|
||||
RibbonServer ribbonServer) {
|
||||
given(this.loadBalancer.getName()).willReturn(ribbonServer.getServiceId());
|
||||
given(this.loadBalancer.chooseServer(anyObject())).willReturn(
|
||||
ribbonServer.getServer());
|
||||
given(this.loadBalancer.getLoadBalancerStats())
|
||||
.willReturn(this.loadBalancerStats);
|
||||
given(this.loadBalancerStats.getSingleServerStat(ribbonServer.getServer()))
|
||||
.willReturn(this.serverStats);
|
||||
given(this.clientFactory.getLoadBalancer(this.loadBalancer.getName()))
|
||||
.willReturn(this.loadBalancer);
|
||||
return new RibbonLoadBalancerClient(this.clientFactory);
|
||||
}
|
||||
|
||||
protected RibbonServer getRibbonServer() {
|
||||
return new RibbonServer("testService", new Server("myhost", 9080), false,
|
||||
Collections.singletonMap("mykey", "myvalue"));
|
||||
}
|
||||
protected RibbonServer getRibbonServer() {
|
||||
return new RibbonServer("testService", new Server("myhost", 9080), false,
|
||||
Collections.singletonMap("mykey", "myvalue"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* 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,
|
||||
@@ -38,58 +38,58 @@ import okhttp3.Request;
|
||||
*/
|
||||
public class RibbonCommandContextTest {
|
||||
|
||||
private static final byte[] TEST_CONTENT = { 42, 42, 42, 42, 42 };
|
||||
private static final byte[] TEST_CONTENT = { 42, 42, 42, 42, 42 };
|
||||
|
||||
private RibbonCommandContext ribbonCommandContext;
|
||||
private RibbonCommandContext ribbonCommandContext;
|
||||
|
||||
@Test
|
||||
public void testMultipleReadsOnRequestEntity() throws Exception {
|
||||
givenRibbonCommandContextIsSetup();
|
||||
@Test
|
||||
public void testMultipleReadsOnRequestEntity() throws Exception {
|
||||
givenRibbonCommandContextIsSetup();
|
||||
|
||||
InputStream requestEntity = ribbonCommandContext.getRequestEntity();
|
||||
assertTrue(requestEntity instanceof ResettableServletInputStreamWrapper);
|
||||
InputStream requestEntity = ribbonCommandContext.getRequestEntity();
|
||||
assertTrue(requestEntity instanceof ResettableServletInputStreamWrapper);
|
||||
|
||||
whenInputStreamIsConsumed(requestEntity);
|
||||
assertEquals(-1, requestEntity.read());
|
||||
whenInputStreamIsConsumed(requestEntity);
|
||||
assertEquals(-1, requestEntity.read());
|
||||
|
||||
requestEntity.reset();
|
||||
assertNotEquals(-1, requestEntity.read());
|
||||
requestEntity.reset();
|
||||
assertNotEquals(-1, requestEntity.read());
|
||||
|
||||
whenInputStreamIsConsumed(requestEntity);
|
||||
assertEquals(-1, requestEntity.read());
|
||||
whenInputStreamIsConsumed(requestEntity);
|
||||
assertEquals(-1, requestEntity.read());
|
||||
|
||||
requestEntity.reset();
|
||||
assertNotEquals(-1, requestEntity.read());
|
||||
requestEntity.reset();
|
||||
assertNotEquals(-1, requestEntity.read());
|
||||
|
||||
whenInputStreamIsConsumed(requestEntity);
|
||||
assertEquals(-1, requestEntity.read());
|
||||
}
|
||||
whenInputStreamIsConsumed(requestEntity);
|
||||
assertEquals(-1, requestEntity.read());
|
||||
}
|
||||
|
||||
private void whenInputStreamIsConsumed(InputStream requestEntity) throws IOException {
|
||||
while (requestEntity.read() != -1) {
|
||||
requestEntity.read();
|
||||
}
|
||||
}
|
||||
private void whenInputStreamIsConsumed(InputStream requestEntity) throws IOException {
|
||||
while (requestEntity.read() != -1) {
|
||||
requestEntity.read();
|
||||
}
|
||||
}
|
||||
|
||||
private void givenRibbonCommandContextIsSetup() {
|
||||
LinkedMultiValueMap headers = new LinkedMultiValueMap();
|
||||
LinkedMultiValueMap params = new LinkedMultiValueMap();
|
||||
private void givenRibbonCommandContextIsSetup() {
|
||||
LinkedMultiValueMap headers = new LinkedMultiValueMap();
|
||||
LinkedMultiValueMap params = new LinkedMultiValueMap();
|
||||
|
||||
RibbonRequestCustomizer requestCustomizer = new RibbonRequestCustomizer<Request.Builder>() {
|
||||
@Override
|
||||
public boolean accepts(Class builderClass) {
|
||||
return builderClass == Request.Builder.class;
|
||||
}
|
||||
RibbonRequestCustomizer requestCustomizer = new RibbonRequestCustomizer<Request.Builder>() {
|
||||
@Override
|
||||
public boolean accepts(Class builderClass) {
|
||||
return builderClass == Request.Builder.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(Request.Builder builder) {
|
||||
builder.addHeader("from-customizer", "foo");
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public void customize(Request.Builder builder) {
|
||||
builder.addHeader("from-customizer", "foo");
|
||||
}
|
||||
};
|
||||
|
||||
ribbonCommandContext = new RibbonCommandContext("serviceId",
|
||||
HttpMethod.POST.toString(), "/my/route", true, headers, params,
|
||||
new ByteArrayInputStream(TEST_CONTENT),
|
||||
Lists.newArrayList(requestCustomizer));
|
||||
}
|
||||
ribbonCommandContext = new RibbonCommandContext("serviceId",
|
||||
HttpMethod.POST.toString(), "/my/route", true, headers, params,
|
||||
new ByteArrayInputStream(TEST_CONTENT),
|
||||
Lists.newArrayList(requestCustomizer));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -49,33 +49,33 @@ import static com.netflix.appinfo.InstanceInfo.InstanceStatus;
|
||||
*/
|
||||
public class EurekaHealthCheckHandler implements HealthCheckHandler, ApplicationContextAware, InitializingBean {
|
||||
|
||||
private static final Map<Status, InstanceInfo.InstanceStatus> STATUS_MAPPING =
|
||||
new HashMap<Status, InstanceInfo.InstanceStatus>() {{
|
||||
put(Status.UNKNOWN, InstanceStatus.UNKNOWN);
|
||||
put(Status.OUT_OF_SERVICE, InstanceStatus.OUT_OF_SERVICE);
|
||||
put(Status.DOWN, InstanceStatus.DOWN);
|
||||
put(Status.UP, InstanceStatus.UP);
|
||||
}};
|
||||
private static final Map<Status, InstanceInfo.InstanceStatus> STATUS_MAPPING =
|
||||
new HashMap<Status, InstanceInfo.InstanceStatus>() {{
|
||||
put(Status.UNKNOWN, InstanceStatus.UNKNOWN);
|
||||
put(Status.OUT_OF_SERVICE, InstanceStatus.OUT_OF_SERVICE);
|
||||
put(Status.DOWN, InstanceStatus.DOWN);
|
||||
put(Status.UP, InstanceStatus.UP);
|
||||
}};
|
||||
|
||||
private final CompositeHealthIndicator healthIndicator;
|
||||
private final CompositeHealthIndicator healthIndicator;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
public EurekaHealthCheckHandler(HealthAggregator healthAggregator) {
|
||||
Assert.notNull(healthAggregator, "HealthAggregator must not be null");
|
||||
this.healthIndicator = new CompositeHealthIndicator(healthAggregator);
|
||||
}
|
||||
public EurekaHealthCheckHandler(HealthAggregator healthAggregator) {
|
||||
Assert.notNull(healthAggregator, "HealthAggregator must not be null");
|
||||
this.healthIndicator = new CompositeHealthIndicator(healthAggregator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
final Map<String, HealthIndicator> healthIndicators = applicationContext.getBeansOfType(HealthIndicator.class);
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
final Map<String, HealthIndicator> healthIndicators = applicationContext.getBeansOfType(HealthIndicator.class);
|
||||
|
||||
for (Map.Entry<String, HealthIndicator> entry : healthIndicators.entrySet()) {
|
||||
for (Map.Entry<String, HealthIndicator> entry : healthIndicators.entrySet()) {
|
||||
|
||||
//ignore EurekaHealthIndicator and flatten the rest of the composite
|
||||
//otherwise there is a never ending cycle of down. See gh-643
|
||||
@@ -91,23 +91,23 @@ public class EurekaHealthCheckHandler implements HealthCheckHandler, Application
|
||||
else {
|
||||
healthIndicator.addHealthIndicator(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceStatus getStatus(InstanceStatus instanceStatus) {
|
||||
return getHealthStatus();
|
||||
}
|
||||
@Override
|
||||
public InstanceStatus getStatus(InstanceStatus instanceStatus) {
|
||||
return getHealthStatus();
|
||||
}
|
||||
|
||||
protected InstanceStatus getHealthStatus() {
|
||||
final Status status = healthIndicator.health().getStatus();
|
||||
return mapToInstanceStatus(status);
|
||||
}
|
||||
protected InstanceStatus getHealthStatus() {
|
||||
final Status status = healthIndicator.health().getStatus();
|
||||
return mapToInstanceStatus(status);
|
||||
}
|
||||
|
||||
protected InstanceStatus mapToInstanceStatus(Status status) {
|
||||
if (!STATUS_MAPPING.containsKey(status)) {
|
||||
return InstanceStatus.UNKNOWN;
|
||||
}
|
||||
return STATUS_MAPPING.get(status);
|
||||
}
|
||||
protected InstanceStatus mapToInstanceStatus(Status status) {
|
||||
if (!STATUS_MAPPING.containsKey(status)) {
|
||||
return InstanceStatus.UNKNOWN;
|
||||
}
|
||||
return STATUS_MAPPING.get(status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -42,47 +42,47 @@ import static org.junit.Assert.assertEquals;
|
||||
*/
|
||||
public class EurekaHealthCheckHandlerTests {
|
||||
|
||||
private EurekaHealthCheckHandler healthCheckHandler;
|
||||
private EurekaHealthCheckHandler healthCheckHandler;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
healthCheckHandler = new EurekaHealthCheckHandler(new OrderedHealthAggregator());
|
||||
}
|
||||
healthCheckHandler = new EurekaHealthCheckHandler(new OrderedHealthAggregator());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoHealthCheckRegistered() throws Exception {
|
||||
@Test
|
||||
public void testNoHealthCheckRegistered() throws Exception {
|
||||
|
||||
InstanceStatus status = healthCheckHandler.getStatus(InstanceStatus.UNKNOWN);
|
||||
assertEquals(InstanceStatus.UNKNOWN, status);
|
||||
}
|
||||
InstanceStatus status = healthCheckHandler.getStatus(InstanceStatus.UNKNOWN);
|
||||
assertEquals(InstanceStatus.UNKNOWN, status);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllUp() throws Exception {
|
||||
@Test
|
||||
public void testAllUp() throws Exception {
|
||||
|
||||
initialize(UpHealthConfiguration.class);
|
||||
initialize(UpHealthConfiguration.class);
|
||||
|
||||
InstanceStatus status = healthCheckHandler.getStatus(InstanceStatus.UNKNOWN);
|
||||
assertEquals(InstanceStatus.UP, status);
|
||||
}
|
||||
InstanceStatus status = healthCheckHandler.getStatus(InstanceStatus.UNKNOWN);
|
||||
assertEquals(InstanceStatus.UP, status);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDown() throws Exception {
|
||||
@Test
|
||||
public void testDown() throws Exception {
|
||||
|
||||
initialize(UpHealthConfiguration.class, DownHealthConfiguration.class);
|
||||
initialize(UpHealthConfiguration.class, DownHealthConfiguration.class);
|
||||
|
||||
InstanceStatus status = healthCheckHandler.getStatus(InstanceStatus.UNKNOWN);
|
||||
assertEquals(InstanceStatus.DOWN, status);
|
||||
}
|
||||
InstanceStatus status = healthCheckHandler.getStatus(InstanceStatus.UNKNOWN);
|
||||
assertEquals(InstanceStatus.DOWN, status);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnknown() throws Exception {
|
||||
@Test
|
||||
public void testUnknown() throws Exception {
|
||||
|
||||
initialize(FatalHealthConfiguration.class);
|
||||
initialize(FatalHealthConfiguration.class);
|
||||
|
||||
InstanceStatus status = healthCheckHandler.getStatus(InstanceStatus.UNKNOWN);
|
||||
assertEquals(InstanceStatus.UNKNOWN, status);
|
||||
}
|
||||
InstanceStatus status = healthCheckHandler.getStatus(InstanceStatus.UNKNOWN);
|
||||
assertEquals(InstanceStatus.UNKNOWN, status);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEurekaIgnored() throws Exception {
|
||||
@@ -93,50 +93,50 @@ public class EurekaHealthCheckHandlerTests {
|
||||
assertEquals(InstanceStatus.UP, status);
|
||||
}
|
||||
|
||||
private void initialize(Class<?>... configurations) throws Exception {
|
||||
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(configurations);
|
||||
healthCheckHandler.setApplicationContext(applicationContext);
|
||||
healthCheckHandler.afterPropertiesSet();
|
||||
}
|
||||
private void initialize(Class<?>... configurations) throws Exception {
|
||||
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(configurations);
|
||||
healthCheckHandler.setApplicationContext(applicationContext);
|
||||
healthCheckHandler.afterPropertiesSet();
|
||||
}
|
||||
|
||||
public static class UpHealthConfiguration {
|
||||
public static class UpHealthConfiguration {
|
||||
|
||||
@Bean
|
||||
public HealthIndicator healthIndicator() {
|
||||
return new AbstractHealthIndicator() {
|
||||
@Override
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
builder.up();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@Bean
|
||||
public HealthIndicator healthIndicator() {
|
||||
return new AbstractHealthIndicator() {
|
||||
@Override
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
builder.up();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static class DownHealthConfiguration {
|
||||
public static class DownHealthConfiguration {
|
||||
|
||||
@Bean
|
||||
public HealthIndicator healthIndicator() {
|
||||
return new AbstractHealthIndicator() {
|
||||
@Override
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
builder.down();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@Bean
|
||||
public HealthIndicator healthIndicator() {
|
||||
return new AbstractHealthIndicator() {
|
||||
@Override
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
builder.down();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static class FatalHealthConfiguration {
|
||||
public static class FatalHealthConfiguration {
|
||||
|
||||
@Bean
|
||||
public HealthIndicator healthIndicator() {
|
||||
return new AbstractHealthIndicator() {
|
||||
@Override
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
builder.status("fatal");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@Bean
|
||||
public HealthIndicator healthIndicator() {
|
||||
return new AbstractHealthIndicator() {
|
||||
@Override
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
builder.status("fatal");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class EurekaDownHealthConfiguration {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -33,22 +33,22 @@ import org.springframework.boot.actuate.health.Status;
|
||||
*/
|
||||
class LocalApplicationHealthCheckHandler implements HealthCheckHandler {
|
||||
|
||||
private final HealthIndicator healthIndicator;
|
||||
private final HealthIndicator healthIndicator;
|
||||
|
||||
public LocalApplicationHealthCheckHandler(HealthIndicator healthIndicator) {
|
||||
this.healthIndicator = healthIndicator;
|
||||
}
|
||||
public LocalApplicationHealthCheckHandler(HealthIndicator healthIndicator) {
|
||||
this.healthIndicator = healthIndicator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceStatus getStatus(InstanceStatus currentStatus) {
|
||||
Status status = healthIndicator.health().getStatus();
|
||||
if (status.equals(Status.UP)) {
|
||||
return UP;
|
||||
} else if (status.equals(Status.OUT_OF_SERVICE)) {
|
||||
return OUT_OF_SERVICE;
|
||||
} else if (status.equals(Status.DOWN)) {
|
||||
return DOWN;
|
||||
}
|
||||
return UNKNOWN;
|
||||
}
|
||||
@Override
|
||||
public InstanceStatus getStatus(InstanceStatus currentStatus) {
|
||||
Status status = healthIndicator.health().getStatus();
|
||||
if (status.equals(Status.UP)) {
|
||||
return UP;
|
||||
} else if (status.equals(Status.OUT_OF_SERVICE)) {
|
||||
return OUT_OF_SERVICE;
|
||||
} else if (status.equals(Status.DOWN)) {
|
||||
return DOWN;
|
||||
}
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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,39 +32,39 @@ import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
*/
|
||||
public class LocalApplicationHealthCheckHandlerTests {
|
||||
|
||||
@Mock
|
||||
private HealthIndicator healthIndicator;
|
||||
@Mock
|
||||
private HealthIndicator healthIndicator;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
initMocks(this);
|
||||
}
|
||||
@Before
|
||||
public void setup() {
|
||||
initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void upMappingWorks() {
|
||||
assertStatus(InstanceStatus.UP, Health.up());
|
||||
}
|
||||
@Test
|
||||
public void upMappingWorks() {
|
||||
assertStatus(InstanceStatus.UP, Health.up());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void downMappingWorks() {
|
||||
assertStatus(InstanceStatus.DOWN, Health.down());
|
||||
}
|
||||
@Test
|
||||
public void downMappingWorks() {
|
||||
assertStatus(InstanceStatus.DOWN, Health.down());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outOfServiceMappingWorks() {
|
||||
assertStatus(InstanceStatus.OUT_OF_SERVICE, Health.outOfService());
|
||||
}
|
||||
@Test
|
||||
public void outOfServiceMappingWorks() {
|
||||
assertStatus(InstanceStatus.OUT_OF_SERVICE, Health.outOfService());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unknownMappingWorks() {
|
||||
assertStatus(InstanceStatus.UNKNOWN, Health.unknown());
|
||||
}
|
||||
@Test
|
||||
public void unknownMappingWorks() {
|
||||
assertStatus(InstanceStatus.UNKNOWN, Health.unknown());
|
||||
}
|
||||
|
||||
private void assertStatus(InstanceStatus expected, Health.Builder builder) {
|
||||
given(healthIndicator.health()).willReturn(builder.build());
|
||||
private void assertStatus(InstanceStatus expected, Health.Builder builder) {
|
||||
given(healthIndicator.health()).willReturn(builder.build());
|
||||
|
||||
LocalApplicationHealthCheckHandler handler = new LocalApplicationHealthCheckHandler(healthIndicator);
|
||||
InstanceStatus status = handler.getStatus(InstanceStatus.UP);
|
||||
assertEquals(expected, status);
|
||||
}
|
||||
LocalApplicationHealthCheckHandler handler = new LocalApplicationHealthCheckHandler(healthIndicator);
|
||||
InstanceStatus status = handler.getStatus(InstanceStatus.UP);
|
||||
assertEquals(expected, status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -39,70 +39,70 @@ import rx.subjects.PublishSubject;
|
||||
@Component // needed for ServiceActivator to be picked up
|
||||
public class HystrixStreamAggregator {
|
||||
|
||||
private static final Log log = LogFactory.getLog(HystrixStreamAggregator.class);
|
||||
private static final Log log = LogFactory.getLog(HystrixStreamAggregator.class);
|
||||
|
||||
private ObjectMapper objectMapper;
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
private PublishSubject<Map<String, Object>> subject;
|
||||
private PublishSubject<Map<String, Object>> subject;
|
||||
|
||||
@Autowired
|
||||
public HystrixStreamAggregator(ObjectMapper objectMapper,
|
||||
PublishSubject<Map<String, Object>> subject) {
|
||||
this.objectMapper = objectMapper;
|
||||
this.subject = subject;
|
||||
}
|
||||
@Autowired
|
||||
public HystrixStreamAggregator(ObjectMapper objectMapper,
|
||||
PublishSubject<Map<String, Object>> subject) {
|
||||
this.objectMapper = objectMapper;
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
@ServiceActivator(inputChannel = TurbineStreamClient.INPUT)
|
||||
public void sendToSubject(@Payload String payload) {
|
||||
if (payload.startsWith("\"")) {
|
||||
// Legacy payload from an Angel client
|
||||
payload = payload.substring(1, payload.length() - 1);
|
||||
payload = payload.replace("\\\"", "\"");
|
||||
}
|
||||
try {
|
||||
if (payload.startsWith("[")) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> list = this.objectMapper.readValue(payload,
|
||||
List.class);
|
||||
for (Map<String, Object> map : list) {
|
||||
sendMap(map);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> map = this.objectMapper.readValue(payload, Map.class);
|
||||
sendMap(map);
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
log.error("Error receiving hystrix stream payload: " + payload, ex);
|
||||
}
|
||||
}
|
||||
@ServiceActivator(inputChannel = TurbineStreamClient.INPUT)
|
||||
public void sendToSubject(@Payload String payload) {
|
||||
if (payload.startsWith("\"")) {
|
||||
// Legacy payload from an Angel client
|
||||
payload = payload.substring(1, payload.length() - 1);
|
||||
payload = payload.replace("\\\"", "\"");
|
||||
}
|
||||
try {
|
||||
if (payload.startsWith("[")) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> list = this.objectMapper.readValue(payload,
|
||||
List.class);
|
||||
for (Map<String, Object> map : list) {
|
||||
sendMap(map);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> map = this.objectMapper.readValue(payload, Map.class);
|
||||
sendMap(map);
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
log.error("Error receiving hystrix stream payload: " + payload, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMap(Map<String, Object> map) {
|
||||
Map<String, Object> data = getPayloadData(map);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Received hystrix stream payload: " + data);
|
||||
}
|
||||
this.subject.onNext(data);
|
||||
}
|
||||
private void sendMap(Map<String, Object> map) {
|
||||
Map<String, Object> data = getPayloadData(map);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Received hystrix stream payload: " + data);
|
||||
}
|
||||
this.subject.onNext(data);
|
||||
}
|
||||
|
||||
public static Map<String, Object> getPayloadData(Map<String, Object> jsonMap) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> origin = (Map<String, Object>) jsonMap.get("origin");
|
||||
String instanceId = null;
|
||||
if (origin.containsKey("id")) {
|
||||
instanceId = origin.get("id").toString();
|
||||
}
|
||||
if (!StringUtils.hasText(instanceId)) {
|
||||
// TODO: instanceid template
|
||||
instanceId = origin.get("serviceId") + ":" + origin.get("host") + ":"
|
||||
+ origin.get("port");
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> data = (Map<String, Object>) jsonMap.get("data");
|
||||
data.put("instanceId", instanceId);
|
||||
return data;
|
||||
}
|
||||
public static Map<String, Object> getPayloadData(Map<String, Object> jsonMap) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> origin = (Map<String, Object>) jsonMap.get("origin");
|
||||
String instanceId = null;
|
||||
if (origin.containsKey("id")) {
|
||||
instanceId = origin.get("id").toString();
|
||||
}
|
||||
if (!StringUtils.hasText(instanceId)) {
|
||||
// TODO: instanceid template
|
||||
instanceId = origin.get("serviceId") + ":" + origin.get("host") + ":"
|
||||
+ origin.get("port");
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> data = (Map<String, Object>) jsonMap.get("data");
|
||||
data.put("instanceId", instanceId);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -30,58 +30,58 @@ import org.springframework.http.MediaType;
|
||||
@ConfigurationProperties("turbine.stream")
|
||||
public class TurbineStreamProperties {
|
||||
|
||||
@Value("${server.port:8989}")
|
||||
private int port = 8989;
|
||||
@Value("${server.port:8989}")
|
||||
private int port = 8989;
|
||||
|
||||
private String destination = HystrixConstants.HYSTRIX_STREAM_DESTINATION;
|
||||
private String destination = HystrixConstants.HYSTRIX_STREAM_DESTINATION;
|
||||
|
||||
private String contentType = MediaType.APPLICATION_JSON_VALUE;
|
||||
private String contentType = MediaType.APPLICATION_JSON_VALUE;
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getDestination() {
|
||||
return destination;
|
||||
}
|
||||
public String getDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
||||
public void setDestination(String destination) {
|
||||
this.destination = destination;
|
||||
}
|
||||
public void setDestination(String destination) {
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
TurbineStreamProperties that = (TurbineStreamProperties) o;
|
||||
return port == that.port && Objects.equals(destination, that.destination)
|
||||
&& Objects.equals(contentType, that.contentType);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
TurbineStreamProperties that = (TurbineStreamProperties) o;
|
||||
return port == that.port && Objects.equals(destination, that.destination)
|
||||
&& Objects.equals(contentType, that.contentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(port, destination, contentType);
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(port, destination, contentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("TurbineStreamProperties{").append("port=").append(port)
|
||||
.append(", ").append("destination='").append(destination).append("', ")
|
||||
.append("contentType='").append(contentType).append("'}").toString();
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("TurbineStreamProperties{").append("port=").append(port)
|
||||
.append(", ").append("destination='").append(destination).append("', ")
|
||||
.append("contentType='").append(contentType).append("'}").toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -162,8 +162,8 @@ public class CommonsInstanceDiscovery implements InstanceDiscovery {
|
||||
*/
|
||||
Instance marshall(ServiceInstance serviceInstance) {
|
||||
String hostname = serviceInstance.getHost();
|
||||
String managementPort = serviceInstance.getMetadata().get("management.port");
|
||||
String port = managementPort == null ? String.valueOf(serviceInstance.getPort()) : managementPort;
|
||||
String managementPort = serviceInstance.getMetadata().get("management.port");
|
||||
String port = managementPort == null ? String.valueOf(serviceInstance.getPort()) : managementPort;
|
||||
String cluster = getClusterName(serviceInstance);
|
||||
Boolean status = Boolean.TRUE; //TODO: where to get?
|
||||
if (hostname != null && cluster != null && status != null) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -100,23 +100,23 @@ public class CommonsInstanceDiscoveryTests {
|
||||
assertEquals("url is wrong", "http://"+hostName+":"+port+"/hystrix.stream", urlPath);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUseManagementPortFromMetadata() {
|
||||
CommonsInstanceDiscovery discovery = createDiscovery();
|
||||
String appName = "testAppName";
|
||||
int port = 8080;
|
||||
int managementPort = 8081;
|
||||
String hostName = "myhost";
|
||||
DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, hostName, port, false);
|
||||
serviceInstance.getMetadata().put("management.port", String.valueOf(managementPort));
|
||||
Instance instance = discovery.marshall(serviceInstance);
|
||||
assertEquals("port is wrong", String.valueOf(managementPort), instance.getAttributes().get("port"));
|
||||
@Test
|
||||
public void testUseManagementPortFromMetadata() {
|
||||
CommonsInstanceDiscovery discovery = createDiscovery();
|
||||
String appName = "testAppName";
|
||||
int port = 8080;
|
||||
int managementPort = 8081;
|
||||
String hostName = "myhost";
|
||||
DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, hostName, port, false);
|
||||
serviceInstance.getMetadata().put("management.port", String.valueOf(managementPort));
|
||||
Instance instance = discovery.marshall(serviceInstance);
|
||||
assertEquals("port is wrong", String.valueOf(managementPort), instance.getAttributes().get("port"));
|
||||
|
||||
String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure.getUrlPath(instance);
|
||||
assertEquals("url is wrong", "http://"+hostName+":"+managementPort+"/hystrix.stream", urlPath);
|
||||
}
|
||||
String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure.getUrlPath(instance);
|
||||
assertEquals("url is wrong", "http://"+hostName+":"+managementPort+"/hystrix.stream", urlPath);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test
|
||||
public void testGetSecurePort() {
|
||||
CommonsInstanceDiscovery discovery = createDiscovery();
|
||||
String appName = "testAppName";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -66,17 +66,17 @@ public class ServletDetectionFilter extends ZuulFilter {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
HttpServletRequest request = ctx.getRequest();
|
||||
if (!(request instanceof HttpServletRequestWrapper)
|
||||
&& isDispatcherServletRequest(request)) {
|
||||
ctx.set(IS_DISPATCHER_SERVLET_REQUEST_KEY, true);
|
||||
&& isDispatcherServletRequest(request)) {
|
||||
ctx.set(IS_DISPATCHER_SERVLET_REQUEST_KEY, true);
|
||||
} else {
|
||||
ctx.set(IS_DISPATCHER_SERVLET_REQUEST_KEY, false);
|
||||
ctx.set(IS_DISPATCHER_SERVLET_REQUEST_KEY, false);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isDispatcherServletRequest(HttpServletRequest request) {
|
||||
return request.getAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null;
|
||||
}
|
||||
private boolean isDispatcherServletRequest(HttpServletRequest request) {
|
||||
return request.getAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
* Copyright 2013-2017 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,11 +26,11 @@ import org.springframework.http.client.ClientHttpResponse;
|
||||
*/
|
||||
public interface FallbackProvider extends ZuulFallbackProvider {
|
||||
|
||||
/**
|
||||
* Provides a fallback response based on the cause of the failed execution.
|
||||
*
|
||||
* @param cause cause of the main method failure
|
||||
* @return the fallback response
|
||||
*/
|
||||
ClientHttpResponse fallbackResponse(Throwable cause);
|
||||
/**
|
||||
* Provides a fallback response based on the cause of the failed execution.
|
||||
*
|
||||
* @param cause cause of the main method failure
|
||||
* @return the fallback response
|
||||
*/
|
||||
ClientHttpResponse fallbackResponse(Throwable cause);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2017 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.zuul.util;
|
||||
|
||||
import org.springframework.core.io.InputStreamResource;
|
||||
@@ -18,80 +34,80 @@ import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
public class RequestContentDataExtractor {
|
||||
public static MultiValueMap<String, Object> extract(HttpServletRequest request) throws IOException {
|
||||
return (request instanceof MultipartHttpServletRequest) ?
|
||||
extractFromMultipartRequest((MultipartHttpServletRequest) request) :
|
||||
extractFromRequest(request);
|
||||
}
|
||||
public static MultiValueMap<String, Object> extract(HttpServletRequest request) throws IOException {
|
||||
return (request instanceof MultipartHttpServletRequest) ?
|
||||
extractFromMultipartRequest((MultipartHttpServletRequest) request) :
|
||||
extractFromRequest(request);
|
||||
}
|
||||
|
||||
private static MultiValueMap<String, Object> extractFromRequest(HttpServletRequest request) throws IOException {
|
||||
MultiValueMap<String, Object> builder = new LinkedMultiValueMap<>();
|
||||
Set<String> queryParams = findQueryParams(request);
|
||||
private static MultiValueMap<String, Object> extractFromRequest(HttpServletRequest request) throws IOException {
|
||||
MultiValueMap<String, Object> builder = new LinkedMultiValueMap<>();
|
||||
Set<String> queryParams = findQueryParams(request);
|
||||
|
||||
for (Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
|
||||
String key = entry.getKey();
|
||||
for (Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
|
||||
String key = entry.getKey();
|
||||
|
||||
if (!queryParams.contains(key)) {
|
||||
for (String value : entry.getValue()) {
|
||||
builder.add(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!queryParams.contains(key)) {
|
||||
for (String value : entry.getValue()) {
|
||||
builder.add(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static MultiValueMap<String, Object> extractFromMultipartRequest(MultipartHttpServletRequest request)
|
||||
throws IOException {
|
||||
MultiValueMap<String, Object> builder = new LinkedMultiValueMap<>();
|
||||
Set<String> queryParams = findQueryParams(request);
|
||||
private static MultiValueMap<String, Object> extractFromMultipartRequest(MultipartHttpServletRequest request)
|
||||
throws IOException {
|
||||
MultiValueMap<String, Object> builder = new LinkedMultiValueMap<>();
|
||||
Set<String> queryParams = findQueryParams(request);
|
||||
|
||||
for (Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
|
||||
String key = entry.getKey();
|
||||
for (Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
|
||||
String key = entry.getKey();
|
||||
|
||||
if (!queryParams.contains(key)) {
|
||||
for (String value : entry.getValue()) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
String type = request.getMultipartContentType(key);
|
||||
if (!queryParams.contains(key)) {
|
||||
for (String value : entry.getValue()) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
String type = request.getMultipartContentType(key);
|
||||
|
||||
if (type != null) {
|
||||
headers.setContentType(MediaType.valueOf(type));
|
||||
}
|
||||
if (type != null) {
|
||||
headers.setContentType(MediaType.valueOf(type));
|
||||
}
|
||||
|
||||
builder.add(key, new HttpEntity<>(value, headers));
|
||||
}
|
||||
}
|
||||
}
|
||||
builder.add(key, new HttpEntity<>(value, headers));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry<String, List<MultipartFile>> parts : request.getMultiFileMap().entrySet()) {
|
||||
for (MultipartFile file : parts.getValue()) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentDispositionFormData(file.getName(), file.getOriginalFilename());
|
||||
if (file.getContentType() != null) {
|
||||
headers.setContentType(MediaType.valueOf(file.getContentType()));
|
||||
}
|
||||
for (Entry<String, List<MultipartFile>> parts : request.getMultiFileMap().entrySet()) {
|
||||
for (MultipartFile file : parts.getValue()) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentDispositionFormData(file.getName(), file.getOriginalFilename());
|
||||
if (file.getContentType() != null) {
|
||||
headers.setContentType(MediaType.valueOf(file.getContentType()));
|
||||
}
|
||||
|
||||
HttpEntity entity = new HttpEntity<>(new InputStreamResource(file.getInputStream()), headers);
|
||||
builder.add(parts.getKey(), entity);
|
||||
}
|
||||
}
|
||||
HttpEntity entity = new HttpEntity<>(new InputStreamResource(file.getInputStream()), headers);
|
||||
builder.add(parts.getKey(), entity);
|
||||
}
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static Set<String> findQueryParams(HttpServletRequest request) {
|
||||
Set<String> result = new HashSet<>();
|
||||
String query = request.getQueryString();
|
||||
private static Set<String> findQueryParams(HttpServletRequest request) {
|
||||
Set<String> result = new HashSet<>();
|
||||
String query = request.getQueryString();
|
||||
|
||||
if (query != null) {
|
||||
for (String value : StringUtils.tokenizeToStringArray(query, "&")) {
|
||||
if (value.contains("=")) {
|
||||
value = value.substring(0, value.indexOf("="));
|
||||
}
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
if (query != null) {
|
||||
for (String value : StringUtils.tokenizeToStringArray(query, "&")) {
|
||||
if (value.contains("=")) {
|
||||
value = value.substring(0, value.indexOf("="));
|
||||
}
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2017 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.zuul.util;
|
||||
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
@@ -6,18 +22,18 @@ import static org.springframework.cloud.netflix.zuul.filters.support.FilterConst
|
||||
|
||||
public class RequestUtils {
|
||||
|
||||
/**
|
||||
* @deprecated use {@link org.springframework.cloud.netflix.zuul.filters.support.FilterConstants#IS_DISPATCHER_SERVLET_REQUEST_KEY}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String IS_DISPATCHERSERVLETREQUEST = IS_DISPATCHER_SERVLET_REQUEST_KEY;
|
||||
|
||||
public static boolean isDispatcherServletRequest() {
|
||||
return RequestContext.getCurrentContext().getBoolean(IS_DISPATCHER_SERVLET_REQUEST_KEY);
|
||||
}
|
||||
|
||||
public static boolean isZuulServletRequest() {
|
||||
//extra check for dispatcher since ZuulServlet can run from ZuulController
|
||||
return !isDispatcherServletRequest() && RequestContext.getCurrentContext().getZuulEngineRan();
|
||||
}
|
||||
/**
|
||||
* @deprecated use {@link org.springframework.cloud.netflix.zuul.filters.support.FilterConstants#IS_DISPATCHER_SERVLET_REQUEST_KEY}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String IS_DISPATCHERSERVLETREQUEST = IS_DISPATCHER_SERVLET_REQUEST_KEY;
|
||||
|
||||
public static boolean isDispatcherServletRequest() {
|
||||
return RequestContext.getCurrentContext().getBoolean(IS_DISPATCHER_SERVLET_REQUEST_KEY);
|
||||
}
|
||||
|
||||
public static boolean isZuulServletRequest() {
|
||||
//extra check for dispatcher since ZuulServlet can run from ZuulController
|
||||
return !isDispatcherServletRequest() && RequestContext.getCurrentContext().getZuulEngineRan();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user