From b199167eb2087b96ee5720490dbe9c9ceca81e8a Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Wed, 21 Feb 2018 20:10:11 -0500 Subject: [PATCH] Removing Feign --- pom.xml | 8 + .../feign/AnnotatedParameterProcessor.java | 87 -- .../feign/DefaultFeignLoggerFactory.java | 38 - .../cloud/netflix/feign/DefaultTargeter.java | 33 - .../netflix/feign/EnableFeignClients.java | 88 -- .../netflix/feign/FeignAutoConfiguration.java | 210 ----- .../cloud/netflix/feign/FeignClient.java | 114 --- .../netflix/feign/FeignClientFactoryBean.java | 383 --------- .../netflix/feign/FeignClientProperties.java | 209 ----- .../feign/FeignClientSpecification.java | 79 -- .../feign/FeignClientsConfiguration.java | 128 --- .../netflix/feign/FeignClientsRegistrar.java | 398 --------- .../cloud/netflix/feign/FeignContext.java | 34 - .../feign/FeignFormatterRegistrar.java | 29 - .../netflix/feign/FeignLoggerFactory.java | 36 - .../cloud/netflix/feign/HystrixTargeter.java | 111 --- .../cloud/netflix/feign/Targeter.java | 29 - .../PathVariableParameterProcessor.java | 77 -- .../RequestHeaderParameterProcessor.java | 70 -- .../RequestParamParameterProcessor.java | 73 -- .../encoding/BaseRequestInterceptor.java | 63 -- ...gnAcceptGzipEncodingAutoConfiguration.java | 54 -- .../FeignAcceptGzipEncodingInterceptor.java | 49 -- .../FeignClientEncodingProperties.java | 80 -- ...nContentGzipEncodingAutoConfiguration.java | 54 -- .../FeignContentGzipEncodingInterceptor.java | 111 --- .../netflix/feign/encoding/HttpEncoding.java | 55 -- .../CachingSpringLoadBalancerFactory.java | 113 --- ...DefaultFeignLoadBalancedConfiguration.java | 38 - .../feign/ribbon/FeignLoadBalancer.java | 228 ----- .../feign/ribbon/FeignRetryPolicy.java | 119 --- .../FeignRibbonClientAutoConfiguration.java | 81 -- ...pClientFeignLoadBalancedConfiguration.java | 128 --- .../feign/ribbon/LoadBalancerFeignClient.java | 126 --- .../OkHttpFeignLoadBalancedConfiguration.java | 87 -- .../ribbon/RetryableFeignLoadBalancer.java | 165 ---- .../RibbonResponseStatusCodeException.java | 45 - .../feign/support/FallbackCommand.java | 55 -- .../support/FeignHttpClientProperties.java | 110 --- .../netflix/feign/support/FeignUtils.java | 50 -- .../feign/support/ResponseEntityDecoder.java | 75 -- .../netflix/feign/support/SpringDecoder.java | 111 --- .../netflix/feign/support/SpringEncoder.java | 146 ---- .../feign/support/SpringMvcContract.java | 378 --------- .../main/resources/META-INF/spring.factories | 4 - .../feign/EnableFeignClientsTests.java | 86 -- .../feign/FeignClientFactoryTests.java | 74 -- .../FeignClientOverrideDefaultsTests.java | 227 ----- .../FeignClientUsingPropertiesTests.java | 218 ----- .../feign/FeignClientsRegistrarTests.java | 121 --- .../netflix/feign/FeignCompressionTests.java | 96 --- .../FeignHttpClientConfigurationTests.java | 90 -- .../feign/FeignHttpClientUrlTests.java | 202 ----- .../feign/FeignLoggerFactoryTests.java | 126 --- .../feign/FeignOkHttpConfigurationTests.java | 72 -- .../netflix/feign/SpringDecoderTests.java | 249 ------ .../feign/SpringRetryDisabledTests.java | 74 -- .../feign/SpringRetryEnabledTests.java | 62 -- .../netflix/feign/beans/FeignClientTests.java | 135 --- .../cloud/netflix/feign/beans/TestClient.java | 28 - .../netflix/feign/beans/extra/TestClient.java | 28 - .../encoding/FeignAcceptEncodingTests.java | 96 --- .../encoding/FeignContentEncodingTests.java | 99 --- .../netflix/feign/encoding/Invoices.java | 43 - .../encoding/app/client/InvoiceClient.java | 41 - .../feign/encoding/app/domain/Invoice.java | 47 - .../app/resource/InvoiceResource.java | 63 -- .../invalid/FeignClientValidationTests.java | 283 ------ ...CachingSpringLoadBalancerFactoryTests.java | 136 --- .../feign/ribbon/FeignLoadBalancerTests.java | 171 ---- .../ribbon/FeignRibbonClientPathTests.java | 180 ---- .../ribbon/FeignRibbonClientRetryTests.java | 149 ---- .../feign/ribbon/FeignRibbonClientTests.java | 128 --- ...ignRibbonHttpClientConfigurationTests.java | 87 -- ...nRibbonOkHttpClientConfigurationTests.java | 70 -- .../LoadBalancerFeignClientOverrideTests.java | 121 --- .../RetryableFeignLoadBalancerTests.java | 525 ------------ ...RibbonResponseStatusCodeExceptionTest.java | 60 -- .../FeignHttpClientPropertiesTests.java | 98 --- .../feign/support/SpringEncoderTests.java | 195 ----- .../feign/support/SpringMvcContractTests.java | 594 ------------- .../netflix/feign/testclients/TestClient.java | 32 - .../valid/FeignClientNotPrimaryTests.java | 166 ---- .../netflix/feign/valid/FeignClientTests.java | 802 ------------------ .../valid/FeignClientValidationTests.java | 109 --- .../feign/valid/FeignHttpClientTests.java | 239 ------ .../netflix/feign/valid/FeignOkHttpTests.java | 242 ------ .../scanning/FeignClientEnvVarTests.java | 90 -- .../scanning/FeignClientScanningTests.java | 120 --- .../security/HystrixSecurityApplication.java | 3 - .../security/HystrixSecurityTests.java | 101 --- .../security/app/ProxyUsernameController.java | 36 - .../hystrix/security/app/UsernameClient.java | 30 - .../ApacheHttpClientConfigurationTests.java | 167 ---- .../test/OkHttpClientConfigurationTests.java | 129 --- .../resources/feign-properties.properties | 21 - spring-cloud-netflix-dependencies/pom.xml | 5 - spring-cloud-netflix-zuul/pom.xml | 5 + .../filters/CustomHostRoutingFilterTests.java | 2 +- spring-cloud-starter-netflix/pom.xml | 1 - .../spring-cloud-starter-openfeign/pom.xml | 62 -- .../main/resources/META-INF/spring.provides | 1 - 102 files changed, 14 insertions(+), 12182 deletions(-) delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/AnnotatedParameterProcessor.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/DefaultFeignLoggerFactory.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/DefaultTargeter.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/EnableFeignClients.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignAutoConfiguration.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClient.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientProperties.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientSpecification.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsConfiguration.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrar.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignContext.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignFormatterRegistrar.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignLoggerFactory.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/HystrixTargeter.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/Targeter.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/annotation/PathVariableParameterProcessor.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/annotation/RequestHeaderParameterProcessor.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/annotation/RequestParamParameterProcessor.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/BaseRequestInterceptor.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignAcceptGzipEncodingAutoConfiguration.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignAcceptGzipEncodingInterceptor.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignClientEncodingProperties.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignContentGzipEncodingAutoConfiguration.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignContentGzipEncodingInterceptor.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/HttpEncoding.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/CachingSpringLoadBalancerFactory.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/DefaultFeignLoadBalancedConfiguration.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignLoadBalancer.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignRetryPolicy.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientAutoConfiguration.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/HttpClientFeignLoadBalancedConfiguration.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/LoadBalancerFeignClient.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/OkHttpFeignLoadBalancedConfiguration.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/RetryableFeignLoadBalancer.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/RibbonResponseStatusCodeException.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/FallbackCommand.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/FeignHttpClientProperties.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/FeignUtils.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/ResponseEntityDecoder.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringDecoder.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringEncoder.java delete mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringMvcContract.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/EnableFeignClientsTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientFactoryTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientOverrideDefaultsTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientUsingPropertiesTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrarTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignCompressionTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignHttpClientConfigurationTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignHttpClientUrlTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignLoggerFactoryTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignOkHttpConfigurationTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/SpringDecoderTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/SpringRetryDisabledTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/SpringRetryEnabledTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/beans/FeignClientTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/beans/TestClient.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/beans/extra/TestClient.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/FeignAcceptEncodingTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/FeignContentEncodingTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/Invoices.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/app/client/InvoiceClient.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/app/domain/Invoice.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/app/resource/InvoiceResource.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/invalid/FeignClientValidationTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/CachingSpringLoadBalancerFactoryTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignLoadBalancerTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientPathTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientRetryTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonHttpClientConfigurationTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonOkHttpClientConfigurationTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/LoadBalancerFeignClientOverrideTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/RetryableFeignLoadBalancerTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/RibbonResponseStatusCodeExceptionTest.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/FeignHttpClientPropertiesTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringEncoderTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringMvcContractTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/testclients/TestClient.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientNotPrimaryTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientValidationTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignHttpClientTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignOkHttpTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/scanning/FeignClientEnvVarTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/scanning/FeignClientScanningTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/ProxyUsernameController.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/UsernameClient.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/test/ApacheHttpClientConfigurationTests.java delete mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/test/OkHttpClientConfigurationTests.java delete mode 100644 spring-cloud-netflix-core/src/test/resources/feign-properties.properties delete mode 100644 spring-cloud-starter-netflix/spring-cloud-starter-openfeign/pom.xml delete mode 100644 spring-cloud-starter-netflix/spring-cloud-starter-openfeign/src/main/resources/META-INF/spring.provides diff --git a/pom.xml b/pom.xml index e95e37b68..afdd40a69 100644 --- a/pom.xml +++ b/pom.xml @@ -25,6 +25,7 @@ 2.7.3 2.0.0.BUILD-SNAPSHOT 2.0.0.BUILD-SNAPSHOT + 2.0.0.BUILD-SNAPSHOT Elmhurst.BUILD-SNAPSHOT 1.2.0.RELEASE @@ -118,6 +119,13 @@ pom import + + org.springframework.cloud + spring-cloud-openfeign-dependencies + ${spring-cloud-openfeign.version} + pom + import + com.fasterxml.jackson.dataformat jackson-dataformat-smile diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/AnnotatedParameterProcessor.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/AnnotatedParameterProcessor.java deleted file mode 100644 index 7ec99d353..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/AnnotatedParameterProcessor.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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.feign; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.Collection; - -import feign.MethodMetadata; - -/** - * Feign contract method parameter processor. - * - * @author Jakub Narloch - * @author Abhijit Sarkar - */ -public interface AnnotatedParameterProcessor { - - /** - * Retrieves the processor supported annotation type. - * - * @return the annotation type - */ - Class getAnnotationType(); - - /** - * Process the annotated parameter. - * - * @param context the parameter context - * @param annotation the annotation instance - * @param method the method that contains the annotation - * @return whether the parameter is http - */ - boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method); - - /** - * Specifies the parameter context. - * - * @author Jakub Narloch - */ - interface AnnotatedParameterContext { - - /** - * Retrieves the method metadata. - * - * @return the method metadata - */ - MethodMetadata getMethodMetadata(); - - /** - * Retrieves the index of the parameter. - * - * @return the parameter index - */ - int getParameterIndex(); - - /** - * Sets the parameter name. - * - * @param name the name of the parameter - */ - void setParameterName(String name); - - /** - * Sets the template parameter. - * - * @param name the template parameter - * @param rest the existing parameter values - * @return parameters - */ - Collection setTemplateParameter(String name, Collection rest); - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/DefaultFeignLoggerFactory.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/DefaultFeignLoggerFactory.java deleted file mode 100644 index d7ca25d18..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/DefaultFeignLoggerFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 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. - */ - -package org.springframework.cloud.netflix.feign; - -import feign.Logger; -import feign.slf4j.Slf4jLogger; - -/** - * @author Venil Noronha - */ -public class DefaultFeignLoggerFactory implements FeignLoggerFactory { - - private Logger logger; - - public DefaultFeignLoggerFactory(Logger logger) { - this.logger = logger; - } - - @Override - public Logger create(Class type) { - return this.logger != null ? this.logger : new Slf4jLogger(type); - } - -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/DefaultTargeter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/DefaultTargeter.java deleted file mode 100644 index a51a07932..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/DefaultTargeter.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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. - * - */ - -package org.springframework.cloud.netflix.feign; - -import feign.Feign; -import feign.Target; - -/** - * @author Spencer Gibb - */ -class DefaultTargeter implements Targeter { - - @Override - public T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context, - Target.HardCodedTarget target) { - return feign.target(target); - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/EnableFeignClients.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/EnableFeignClients.java deleted file mode 100644 index 32029a738..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/EnableFeignClients.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2013-2015 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.feign; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.context.annotation.Import; - -/** - * Scans for interfaces that declare they are feign clients (via {@link FeignClient - * @FeignClient}). Configures component scanning directives for use with - * {@link org.springframework.context.annotation.Configuration - * @Configuration} classes. - * - * @author Spencer Gibb - * @author Dave Syer - * @since 1.0 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@Documented -@Import(FeignClientsRegistrar.class) -public @interface EnableFeignClients { - - /** - * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation - * declarations e.g.: {@code @ComponentScan("org.my.pkg")} instead of - * {@code @ComponentScan(basePackages="org.my.pkg")}. - * @return the array of 'basePackages'. - */ - String[] value() default {}; - - /** - * Base packages to scan for annotated components. - *

- * {@link #value()} is an alias for (and mutually exclusive with) this attribute. - *

- * Use {@link #basePackageClasses()} for a type-safe alternative to String-based - * package names. - * - * @return the array of 'basePackages'. - */ - String[] basePackages() default {}; - - /** - * Type-safe alternative to {@link #basePackages()} for specifying the packages to - * scan for annotated components. The package of each class specified will be scanned. - *

- * Consider creating a special no-op marker class or interface in each package that - * serves no purpose other than being referenced by this attribute. - * - * @return the array of 'basePackageClasses'. - */ - Class[] basePackageClasses() default {}; - - /** - * A custom @Configuration for all feign clients. Can contain override - * @Bean definition for the pieces that make up the client, for instance - * {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}. - * - * @see FeignClientsConfiguration for the defaults - */ - Class[] defaultConfiguration() default {}; - - /** - * List of classes annotated with @FeignClient. If not empty, disables classpath scanning. - * @return - */ - Class[] clients() default {}; -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignAutoConfiguration.java deleted file mode 100644 index 75cc6c572..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignAutoConfiguration.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright 2013-2015 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.feign; - -import java.util.ArrayList; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.TimeUnit; - -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.config.RegistryBuilder; -import org.apache.http.conn.HttpClientConnectionManager; -import org.apache.http.impl.client.CloseableHttpClient; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; -import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory; -import org.springframework.cloud.commons.httpclient.OkHttpClientFactory; -import org.springframework.cloud.netflix.feign.support.FeignHttpClientProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import feign.Client; -import feign.Feign; -import feign.httpclient.ApacheHttpClient; -import feign.okhttp.OkHttpClient; -import okhttp3.ConnectionPool; - -import javax.annotation.PreDestroy; - -/** - * @author Spencer Gibb - * @author Julien Roy - */ -@Configuration -@ConditionalOnClass(Feign.class) -@EnableConfigurationProperties({FeignClientProperties.class, FeignHttpClientProperties.class}) -public class FeignAutoConfiguration { - - @Autowired(required = false) - private List configurations = new ArrayList<>(); - - @Bean - public HasFeatures feignFeature() { - return HasFeatures.namedFeature("Feign", Feign.class); - } - - @Bean - public FeignContext feignContext() { - FeignContext context = new FeignContext(); - context.setConfigurations(this.configurations); - return context; - } - - @Configuration - @ConditionalOnClass(name = "feign.hystrix.HystrixFeign") - protected static class HystrixFeignTargeterConfiguration { - @Bean - @ConditionalOnMissingBean - public Targeter feignTargeter() { - return new HystrixTargeter(); - } - } - - @Configuration - @ConditionalOnMissingClass("feign.hystrix.HystrixFeign") - protected static class DefaultFeignTargeterConfiguration { - @Bean - @ConditionalOnMissingBean - public Targeter feignTargeter() { - return new DefaultTargeter(); - } - } - - // the following configuration is for alternate feign clients if - // ribbon is not on the class path. - // see corresponding configurations in FeignRibbonClientAutoConfiguration - // for load balanced ribbon clients. - @Configuration - @ConditionalOnClass(ApacheHttpClient.class) - @ConditionalOnMissingClass("com.netflix.loadbalancer.ILoadBalancer") - @ConditionalOnMissingBean(CloseableHttpClient.class) - @ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true) - protected static class HttpClientFeignConfiguration { - private final Timer connectionManagerTimer = new Timer( - "FeignApacheHttpClientConfiguration.connectionManagerTimer", true); - - @Autowired(required = false) - private RegistryBuilder registryBuilder; - - private CloseableHttpClient httpClient; - - @Bean - @ConditionalOnMissingBean(HttpClientConnectionManager.class) - public HttpClientConnectionManager connectionManager( - ApacheHttpClientConnectionManagerFactory connectionManagerFactory, - FeignHttpClientProperties httpClientProperties) { - final HttpClientConnectionManager connectionManager = connectionManagerFactory - .newConnectionManager(httpClientProperties.isDisableSslValidation(), httpClientProperties.getMaxConnections(), - httpClientProperties.getMaxConnectionsPerRoute(), - httpClientProperties.getTimeToLive(), - httpClientProperties.getTimeToLiveUnit(), registryBuilder); - this.connectionManagerTimer.schedule(new TimerTask() { - @Override - public void run() { - connectionManager.closeExpiredConnections(); - } - }, 30000, httpClientProperties.getConnectionTimerRepeat()); - return connectionManager; - } - - @Bean - public CloseableHttpClient httpClient(ApacheHttpClientFactory httpClientFactory, - HttpClientConnectionManager httpClientConnectionManager, - FeignHttpClientProperties httpClientProperties) { - RequestConfig defaultRequestConfig = RequestConfig.custom() - .setConnectTimeout(httpClientProperties.getConnectionTimeout()) - .setRedirectsEnabled(httpClientProperties.isFollowRedirects()) - .build(); - this.httpClient = httpClientFactory.createBuilder(). - setConnectionManager(httpClientConnectionManager). - setDefaultRequestConfig(defaultRequestConfig).build(); - return this.httpClient; - } - - @Bean - @ConditionalOnMissingBean(Client.class) - public Client feignClient(HttpClient httpClient) { - return new ApacheHttpClient(httpClient); - } - - @PreDestroy - public void destroy() throws Exception { - connectionManagerTimer.cancel(); - if(httpClient != null) { - httpClient.close(); - } - } - } - - @Configuration - @ConditionalOnClass(OkHttpClient.class) - @ConditionalOnMissingClass("com.netflix.loadbalancer.ILoadBalancer") - @ConditionalOnMissingBean(okhttp3.OkHttpClient.class) - @ConditionalOnProperty(value = "feign.okhttp.enabled") - protected static class OkHttpFeignConfiguration { - - private okhttp3.OkHttpClient okHttpClient; - - @Bean - @ConditionalOnMissingBean(ConnectionPool.class) - public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties, - OkHttpClientConnectionPoolFactory connectionPoolFactory) { - Integer maxTotalConnections = httpClientProperties.getMaxConnections(); - Long timeToLive = httpClientProperties.getTimeToLive(); - TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit(); - return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit); - } - - @Bean - public okhttp3.OkHttpClient client(OkHttpClientFactory httpClientFactory, - ConnectionPool connectionPool, FeignHttpClientProperties httpClientProperties) { - Boolean followRedirects = httpClientProperties.isFollowRedirects(); - Integer connectTimeout = httpClientProperties.getConnectionTimeout(); - Boolean disableSslValidation = httpClientProperties.isDisableSslValidation(); - this.okHttpClient = httpClientFactory.createBuilder(disableSslValidation). - connectTimeout(connectTimeout, TimeUnit.MILLISECONDS). - followRedirects(followRedirects). - connectionPool(connectionPool).build(); - return this.okHttpClient; - } - - @PreDestroy - public void destroy() { - if(okHttpClient != null) { - okHttpClient.dispatcher().executorService().shutdown(); - okHttpClient.connectionPool().evictAll(); - } - } - - @Bean - @ConditionalOnMissingBean(Client.class) - public Client feignClient() { - return new OkHttpClient(this.okHttpClient); - } - } - -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClient.java deleted file mode 100644 index 0a40573cb..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClient.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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. - */ - -package org.springframework.cloud.netflix.feign; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.core.annotation.AliasFor; - -/** - * Annotation for interfaces declaring that a REST client with that interface should be - * created (e.g. for autowiring into another component). If ribbon is available it will be - * used to load balance the backend requests, and the load balancer can be configured - * using a @RibbonClient with the same name (i.e. value) as the feign client. - * - * @author Spencer Gibb - * @author Venil Noronha - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface FeignClient { - - /** - * The name of the service with optional protocol prefix. Synonym for {@link #name() - * name}. A name must be specified for all clients, whether or not a url is provided. - * Can be specified as property key, eg: ${propertyKey}. - */ - @AliasFor("name") - String value() default ""; - - /** - * The service id with optional protocol prefix. Synonym for {@link #value() value}. - * - * @deprecated use {@link #name() name} instead - */ - @Deprecated - String serviceId() default ""; - - /** - * The service id with optional protocol prefix. Synonym for {@link #value() value}. - */ - @AliasFor("value") - String name() default ""; - - /** - * Sets the @Qualifier value for the feign client. - */ - String qualifier() default ""; - - /** - * An absolute URL or resolvable hostname (the protocol is optional). - */ - String url() default ""; - - /** - * Whether 404s should be decoded instead of throwing FeignExceptions - */ - boolean decode404() default false; - - /** - * A custom @Configuration for the feign client. Can contain override - * @Bean definition for the pieces that make up the client, for instance - * {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}. - * - * @see FeignClientsConfiguration for the defaults - */ - Class[] configuration() default {}; - - /** - * Fallback class for the specified Feign client interface. The fallback class must - * implement the interface annotated by this annotation and be a valid spring bean. - */ - Class fallback() default void.class; - - /** - * Define a fallback factory for the specified Feign client interface. The fallback - * factory must produce instances of fallback classes that implement the interface - * annotated by {@link FeignClient}. The fallback factory must be a valid spring - * bean. - * - * @see feign.hystrix.FallbackFactory for details. - */ - Class fallbackFactory() default void.class; - - /** - * Path prefix to be used by all method-level mappings. Can be used with or without - * @RibbonClient. - */ - String path() default ""; - - /** - * Whether to mark the feign proxy as a primary bean. Defaults to true. - */ - boolean primary() default true; - -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java deleted file mode 100644 index 1b6d030fb..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java +++ /dev/null @@ -1,383 +0,0 @@ -/* - * Copyright 2013-2018 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.feign; - -import java.util.Map; -import java.util.Objects; - -import org.springframework.beans.BeanUtils; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -import feign.Client; -import feign.Contract; -import feign.Feign; -import feign.Logger; -import feign.Request; -import feign.RequestInterceptor; -import feign.Retryer; -import feign.Target.HardCodedTarget; -import feign.codec.Decoder; -import feign.codec.Encoder; -import feign.codec.ErrorDecoder; - -/** - * @author Spencer Gibb - * @author Venil Noronha - * @author Eko Kurniawan Khannedy - * @author Gregor Zurowski - */ -class FeignClientFactoryBean implements FactoryBean, InitializingBean, - ApplicationContextAware { - /*********************************** - * WARNING! Nothing in this class should be @Autowired. It causes NPEs because of some lifecycle race condition. - ***********************************/ - - private Class type; - - private String name; - - private String url; - - private String path; - - private boolean decode404; - - private ApplicationContext applicationContext; - - private Class fallback = void.class; - - private Class fallbackFactory = void.class; - - @Override - public void afterPropertiesSet() throws Exception { - Assert.hasText(this.name, "Name must be set"); - } - - @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { - this.applicationContext = context; - } - - protected Feign.Builder feign(FeignContext context) { - FeignLoggerFactory loggerFactory = get(context, FeignLoggerFactory.class); - Logger logger = loggerFactory.create(this.type); - - // @formatter:off - Feign.Builder builder = get(context, Feign.Builder.class) - // required values - .logger(logger) - .encoder(get(context, Encoder.class)) - .decoder(get(context, Decoder.class)) - .contract(get(context, Contract.class)); - // @formatter:on - - configureFeign(context, builder); - - return builder; - } - - protected void configureFeign(FeignContext context, Feign.Builder builder) { - FeignClientProperties properties = applicationContext.getBean(FeignClientProperties.class); - if (properties != null) { - if (properties.isDefaultToProperties()) { - configureUsingConfiguration(context, builder); - configureUsingProperties(properties.getConfig().get(properties.getDefaultConfig()), builder); - configureUsingProperties(properties.getConfig().get(this.name), builder); - } else { - configureUsingProperties(properties.getConfig().get(properties.getDefaultConfig()), builder); - configureUsingProperties(properties.getConfig().get(this.name), builder); - configureUsingConfiguration(context, builder); - } - } else { - configureUsingConfiguration(context, builder); - } - } - - protected void configureUsingConfiguration(FeignContext context, Feign.Builder builder) { - Logger.Level level = getOptional(context, Logger.Level.class); - if (level != null) { - builder.logLevel(level); - } - Retryer retryer = getOptional(context, Retryer.class); - if (retryer != null) { - builder.retryer(retryer); - } - ErrorDecoder errorDecoder = getOptional(context, ErrorDecoder.class); - if (errorDecoder != null) { - builder.errorDecoder(errorDecoder); - } - Request.Options options = getOptional(context, Request.Options.class); - if (options != null) { - builder.options(options); - } - Map requestInterceptors = context.getInstances( - this.name, RequestInterceptor.class); - if (requestInterceptors != null) { - builder.requestInterceptors(requestInterceptors.values()); - } - - if (decode404) { - builder.decode404(); - } - } - - protected void configureUsingProperties(FeignClientProperties.FeignClientConfiguration config, Feign.Builder builder) { - if (config == null) { - return; - } - - if (config.getLoggerLevel() != null) { - builder.logLevel(config.getLoggerLevel()); - } - - if (config.getConnectTimeout() != null && config.getReadTimeout() != null) { - builder.options(new Request.Options(config.getConnectTimeout(), config.getReadTimeout())); - } - - if (config.getRetryer() != null) { - Retryer retryer = getOrInstantiate(config.getRetryer()); - builder.retryer(retryer); - } - - if (config.getErrorDecoder() != null) { - ErrorDecoder errorDecoder = getOrInstantiate(config.getErrorDecoder()); - builder.errorDecoder(errorDecoder); - } - - if (config.getRequestInterceptors() != null && !config.getRequestInterceptors().isEmpty()) { - // this will add request interceptor to builder, not replace existing - for (Class bean : config.getRequestInterceptors()) { - RequestInterceptor interceptor = getOrInstantiate(bean); - builder.requestInterceptor(interceptor); - } - } - - if (config.getDecode404() != null) { - if (config.getDecode404()) { - builder.decode404(); - } - } - - if (Objects.nonNull(config.getEncoder())) { - builder.encoder(getOrInstantiate(config.getEncoder())); - } - - if (Objects.nonNull(config.getDecoder())) { - builder.decoder(getOrInstantiate(config.getDecoder())); - } - - if (Objects.nonNull(config.getContract())) { - builder.contract(getOrInstantiate(config.getContract())); - } - } - - private T getOrInstantiate(Class tClass) { - try { - return applicationContext.getBean(tClass); - } catch (NoSuchBeanDefinitionException e) { - return BeanUtils.instantiateClass(tClass); - } - } - - protected T get(FeignContext context, Class type) { - T instance = context.getInstance(this.name, type); - if (instance == null) { - throw new IllegalStateException("No bean found of type " + type + " for " - + this.name); - } - return instance; - } - - protected T getOptional(FeignContext context, Class type) { - return context.getInstance(this.name, type); - } - - protected T loadBalance(Feign.Builder builder, FeignContext context, - HardCodedTarget target) { - Client client = getOptional(context, Client.class); - if (client != null) { - builder.client(client); - Targeter targeter = get(context, Targeter.class); - return targeter.target(this, builder, context, target); - } - - throw new IllegalStateException( - "No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-netflix-ribbon?"); - } - - @Override - public Object getObject() throws Exception { - FeignContext context = applicationContext.getBean(FeignContext.class); - Feign.Builder builder = feign(context); - - if (!StringUtils.hasText(this.url)) { - String url; - if (!this.name.startsWith("http")) { - url = "http://" + this.name; - } - else { - url = this.name; - } - url += cleanPath(); - return loadBalance(builder, context, new HardCodedTarget<>(this.type, - this.name, url)); - } - if (StringUtils.hasText(this.url) && !this.url.startsWith("http")) { - this.url = "http://" + this.url; - } - String url = this.url + cleanPath(); - Client client = getOptional(context, Client.class); - if (client != null) { - if (client instanceof LoadBalancerFeignClient) { - // not lod balancing because we have a url, - // but ribbon is on the classpath, so unwrap - client = ((LoadBalancerFeignClient)client).getDelegate(); - } - builder.client(client); - } - Targeter targeter = get(context, Targeter.class); - return targeter.target(this, builder, context, new HardCodedTarget<>( - this.type, this.name, url)); - } - - private String cleanPath() { - String path = this.path.trim(); - if (StringUtils.hasLength(path)) { - if (!path.startsWith("/")) { - path = "/" + path; - } - if (path.endsWith("/")) { - path = path.substring(0, path.length() - 1); - } - } - return path; - } - - @Override - public Class getObjectType() { - return this.type; - } - - @Override - public boolean isSingleton() { - return true; - } - - public Class getType() { - return type; - } - - public void setType(Class type) { - this.type = type; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public boolean isDecode404() { - return decode404; - } - - public void setDecode404(boolean decode404) { - this.decode404 = decode404; - } - - public ApplicationContext getApplicationContext() { - return applicationContext; - } - - public Class getFallback() { - return fallback; - } - - public void setFallback(Class fallback) { - this.fallback = fallback; - } - - public Class getFallbackFactory() { - return fallbackFactory; - } - - public void setFallbackFactory(Class fallbackFactory) { - this.fallbackFactory = fallbackFactory; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - FeignClientFactoryBean that = (FeignClientFactoryBean) o; - return Objects.equals(applicationContext, that.applicationContext) && - decode404 == that.decode404 && - Objects.equals(fallback, that.fallback) && - Objects.equals(fallbackFactory, that.fallbackFactory) && - Objects.equals(name, that.name) && - Objects.equals(path, that.path) && - Objects.equals(type, that.type) && - Objects.equals(url, that.url); - } - - @Override - public int hashCode() { - return Objects.hash(applicationContext, decode404, fallback, fallbackFactory, - name, path, type, url); - } - - @Override - public String toString() { - return new StringBuilder("FeignClientFactoryBean{") - .append("type=").append(type).append(", ") - .append("name='").append(name).append("', ") - .append("url='").append(url).append("', ") - .append("path='").append(path).append("', ") - .append("decode404=").append(decode404).append(", ") - .append("applicationContext=").append(applicationContext).append(", ") - .append("fallback=").append(fallback).append(", ") - .append("fallbackFactory=").append(fallbackFactory) - .append("}").toString(); - } - -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientProperties.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientProperties.java deleted file mode 100644 index ac6c1465a..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientProperties.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * 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.feign; - -import feign.Contract; -import feign.Logger; -import feign.RequestInterceptor; -import feign.Retryer; -import feign.codec.Decoder; -import feign.codec.Encoder; -import feign.codec.ErrorDecoder; -import org.springframework.boot.context.properties.ConfigurationProperties; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -/** - * @author Eko Kurniawan Khannedy - */ -@ConfigurationProperties("feign.client") -public class FeignClientProperties { - - private boolean defaultToProperties = true; - - private String defaultConfig = "default"; - - private Map config = new HashMap<>(); - - public boolean isDefaultToProperties() { - return defaultToProperties; - } - - public void setDefaultToProperties(boolean defaultToProperties) { - this.defaultToProperties = defaultToProperties; - } - - public String getDefaultConfig() { - return defaultConfig; - } - - public void setDefaultConfig(String defaultConfig) { - this.defaultConfig = defaultConfig; - } - - public Map getConfig() { - return config; - } - - public void setConfig(Map config) { - this.config = config; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - FeignClientProperties that = (FeignClientProperties) o; - return defaultToProperties == that.defaultToProperties && - Objects.equals(defaultConfig, that.defaultConfig) && - Objects.equals(config, that.config); - } - - @Override - public int hashCode() { - return Objects.hash(defaultToProperties, defaultConfig, config); - } - - public static class FeignClientConfiguration { - - private Logger.Level loggerLevel; - - private Integer connectTimeout; - - private Integer readTimeout; - - private Class retryer; - - private Class errorDecoder; - - private List> requestInterceptors; - - private Boolean decode404; - - private Class decoder; - - private Class encoder; - - private Class contract; - - public Logger.Level getLoggerLevel() { - return loggerLevel; - } - - public void setLoggerLevel(Logger.Level loggerLevel) { - this.loggerLevel = loggerLevel; - } - - public Integer getConnectTimeout() { - return connectTimeout; - } - - public void setConnectTimeout(Integer connectTimeout) { - this.connectTimeout = connectTimeout; - } - - public Integer getReadTimeout() { - return readTimeout; - } - - public void setReadTimeout(Integer readTimeout) { - this.readTimeout = readTimeout; - } - - public Class getRetryer() { - return retryer; - } - - public void setRetryer(Class retryer) { - this.retryer = retryer; - } - - public Class getErrorDecoder() { - return errorDecoder; - } - - public void setErrorDecoder(Class errorDecoder) { - this.errorDecoder = errorDecoder; - } - - public List> getRequestInterceptors() { - return requestInterceptors; - } - - public void setRequestInterceptors(List> requestInterceptors) { - this.requestInterceptors = requestInterceptors; - } - - public Boolean getDecode404() { - return decode404; - } - - public void setDecode404(Boolean decode404) { - this.decode404 = decode404; - } - - public Class getDecoder() { - return decoder; - } - - public void setDecoder(Class decoder) { - this.decoder = decoder; - } - - public Class getEncoder() { - return encoder; - } - - public void setEncoder(Class encoder) { - this.encoder = encoder; - } - - public Class getContract() { - return contract; - } - - public void setContract(Class contract) { - this.contract = contract; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - FeignClientConfiguration that = (FeignClientConfiguration) o; - return loggerLevel == that.loggerLevel && - Objects.equals(connectTimeout, that.connectTimeout) && - Objects.equals(readTimeout, that.readTimeout) && - Objects.equals(retryer, that.retryer) && - Objects.equals(errorDecoder, that.errorDecoder) && - Objects.equals(requestInterceptors, that.requestInterceptors) && - Objects.equals(decode404, that.decode404) && - Objects.equals(encoder, that.encoder) && - Objects.equals(decoder, that.decoder) && - Objects.equals(contract, that.contract); - } - - @Override - public int hashCode() { - return Objects.hash(loggerLevel, connectTimeout, readTimeout, retryer, - errorDecoder, requestInterceptors, decode404, encoder, decoder, contract); - } - } - -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientSpecification.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientSpecification.java deleted file mode 100644 index fdde09df7..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientSpecification.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2013-2015 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.feign; - -import org.springframework.cloud.context.named.NamedContextFactory; - -import java.util.Arrays; -import java.util.Objects; - -/** - * @author Dave Syer - * @author Gregor Zurowski - */ -class FeignClientSpecification implements NamedContextFactory.Specification { - - private String name; - - private Class[] configuration; - - public FeignClientSpecification() {} - - public FeignClientSpecification(String name, Class[] configuration) { - this.name = name; - this.configuration = configuration; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Class[] getConfiguration() { - return configuration; - } - - public void setConfiguration(Class[] configuration) { - this.configuration = configuration; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - FeignClientSpecification that = (FeignClientSpecification) o; - return Objects.equals(name, that.name) && - Arrays.equals(configuration, that.configuration); - } - - @Override - public int hashCode() { - return Objects.hash(name, configuration); - } - - @Override - public String toString() { - return new StringBuilder("FeignClientSpecification{") - .append("name='").append(name).append("', ") - .append("configuration=").append(Arrays.toString(configuration)) - .append("}").toString(); - } - -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsConfiguration.java deleted file mode 100644 index a2feabdbc..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsConfiguration.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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.feign; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.beans.factory.ObjectFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; -import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder; -import org.springframework.cloud.netflix.feign.support.SpringDecoder; -import org.springframework.cloud.netflix.feign.support.SpringEncoder; -import org.springframework.cloud.netflix.feign.support.SpringMvcContract; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Scope; -import org.springframework.core.convert.ConversionService; -import org.springframework.format.support.DefaultFormattingConversionService; -import org.springframework.format.support.FormattingConversionService; - -import com.netflix.hystrix.HystrixCommand; - -import feign.Contract; -import feign.Feign; -import feign.Logger; -import feign.Retryer; -import feign.codec.Decoder; -import feign.codec.Encoder; -import feign.hystrix.HystrixFeign; -import feign.optionals.OptionalDecoder; - -/** - * @author Dave Syer - * @author Venil Noronha - */ -@Configuration -public class FeignClientsConfiguration { - - @Autowired - private ObjectFactory messageConverters; - - @Autowired(required = false) - private List parameterProcessors = new ArrayList<>(); - - @Autowired(required = false) - private List feignFormatterRegistrars = new ArrayList<>(); - - @Autowired(required = false) - private Logger logger; - - @Bean - @ConditionalOnMissingBean - public Decoder feignDecoder() { - return new OptionalDecoder(new ResponseEntityDecoder(new SpringDecoder(this.messageConverters))); - } - - @Bean - @ConditionalOnMissingBean - public Encoder feignEncoder() { - return new SpringEncoder(this.messageConverters); - } - - @Bean - @ConditionalOnMissingBean - public Contract feignContract(ConversionService feignConversionService) { - return new SpringMvcContract(this.parameterProcessors, feignConversionService); - } - - @Bean - public FormattingConversionService feignConversionService() { - FormattingConversionService conversionService = new DefaultFormattingConversionService(); - for (FeignFormatterRegistrar feignFormatterRegistrar : feignFormatterRegistrars) { - feignFormatterRegistrar.registerFormatters(conversionService); - } - return conversionService; - } - - @Configuration - @ConditionalOnClass({ HystrixCommand.class, HystrixFeign.class }) - protected static class HystrixFeignConfiguration { - @Bean - @Scope("prototype") - @ConditionalOnMissingBean - @ConditionalOnProperty(name = "feign.hystrix.enabled") - public Feign.Builder feignHystrixBuilder() { - return HystrixFeign.builder(); - } - } - - @Bean - @ConditionalOnMissingBean - public Retryer feignRetryer() { - return Retryer.NEVER_RETRY; - } - - @Bean - @Scope("prototype") - @ConditionalOnMissingBean - public Feign.Builder feignBuilder(Retryer retryer) { - return Feign.builder().retryer(retryer); - } - - @Bean - @ConditionalOnMissingBean(FeignLoggerFactory.class) - public FeignLoggerFactory feignLoggerFactory() { - return new DefaultFeignLoggerFactory(logger); - } - -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrar.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrar.java deleted file mode 100644 index 58cfd9a93..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrar.java +++ /dev/null @@ -1,398 +0,0 @@ -/* - * 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. - */ - -package org.springframework.cloud.netflix.feign; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.BeanDefinitionHolder; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.context.EnvironmentAware; -import org.springframework.context.ResourceLoaderAware; -import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; -import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; -import org.springframework.core.annotation.AnnotationAttributes; -import org.springframework.core.env.Environment; -import org.springframework.core.io.ResourceLoader; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.core.type.ClassMetadata; -import org.springframework.core.type.classreading.MetadataReader; -import org.springframework.core.type.classreading.MetadataReaderFactory; -import org.springframework.core.type.filter.AbstractClassTestingTypeFilter; -import org.springframework.core.type.filter.AnnotationTypeFilter; -import org.springframework.core.type.filter.TypeFilter; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; - -/** - * @author Spencer Gibb - * @author Jakub Narloch - * @author Venil Noronha - * @author Gang Li - */ -class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, - ResourceLoaderAware, EnvironmentAware { - - // patterned after Spring Integration IntegrationComponentScanRegistrar - // and RibbonClientsConfigurationRegistgrar - - private ResourceLoader resourceLoader; - - private Environment environment; - - public FeignClientsRegistrar() { - } - - @Override - public void setResourceLoader(ResourceLoader resourceLoader) { - this.resourceLoader = resourceLoader; - } - - @Override - public void registerBeanDefinitions(AnnotationMetadata metadata, - BeanDefinitionRegistry registry) { - registerDefaultConfiguration(metadata, registry); - registerFeignClients(metadata, registry); - } - - private void registerDefaultConfiguration(AnnotationMetadata metadata, - BeanDefinitionRegistry registry) { - Map defaultAttrs = metadata - .getAnnotationAttributes(EnableFeignClients.class.getName(), true); - - if (defaultAttrs != null && defaultAttrs.containsKey("defaultConfiguration")) { - String name; - if (metadata.hasEnclosingClass()) { - name = "default." + metadata.getEnclosingClassName(); - } - else { - name = "default." + metadata.getClassName(); - } - registerClientConfiguration(registry, name, - defaultAttrs.get("defaultConfiguration")); - } - } - - public void registerFeignClients(AnnotationMetadata metadata, - BeanDefinitionRegistry registry) { - ClassPathScanningCandidateComponentProvider scanner = getScanner(); - scanner.setResourceLoader(this.resourceLoader); - - Set basePackages; - - Map attrs = metadata - .getAnnotationAttributes(EnableFeignClients.class.getName()); - AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter( - FeignClient.class); - final Class[] clients = attrs == null ? null - : (Class[]) attrs.get("clients"); - if (clients == null || clients.length == 0) { - scanner.addIncludeFilter(annotationTypeFilter); - basePackages = getBasePackages(metadata); - } - else { - final Set clientClasses = new HashSet<>(); - basePackages = new HashSet<>(); - for (Class clazz : clients) { - basePackages.add(ClassUtils.getPackageName(clazz)); - clientClasses.add(clazz.getCanonicalName()); - } - AbstractClassTestingTypeFilter filter = new AbstractClassTestingTypeFilter() { - @Override - protected boolean match(ClassMetadata metadata) { - String cleaned = metadata.getClassName().replaceAll("\\$", "."); - return clientClasses.contains(cleaned); - } - }; - scanner.addIncludeFilter( - new AllTypeFilter(Arrays.asList(filter, annotationTypeFilter))); - } - - for (String basePackage : basePackages) { - Set candidateComponents = scanner - .findCandidateComponents(basePackage); - for (BeanDefinition candidateComponent : candidateComponents) { - if (candidateComponent instanceof AnnotatedBeanDefinition) { - // verify annotated class is an interface - AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent; - AnnotationMetadata annotationMetadata = beanDefinition.getMetadata(); - Assert.isTrue(annotationMetadata.isInterface(), - "@FeignClient can only be specified on an interface"); - - Map attributes = annotationMetadata - .getAnnotationAttributes( - FeignClient.class.getCanonicalName()); - - String name = getClientName(attributes); - registerClientConfiguration(registry, name, - attributes.get("configuration")); - - registerFeignClient(registry, annotationMetadata, attributes); - } - } - } - } - - private void registerFeignClient(BeanDefinitionRegistry registry, - AnnotationMetadata annotationMetadata, Map attributes) { - String className = annotationMetadata.getClassName(); - BeanDefinitionBuilder definition = BeanDefinitionBuilder - .genericBeanDefinition(FeignClientFactoryBean.class); - validate(attributes); - definition.addPropertyValue("url", getUrl(attributes)); - definition.addPropertyValue("path", getPath(attributes)); - String name = getName(attributes); - definition.addPropertyValue("name", name); - definition.addPropertyValue("type", className); - definition.addPropertyValue("decode404", attributes.get("decode404")); - definition.addPropertyValue("fallback", attributes.get("fallback")); - definition.addPropertyValue("fallbackFactory", attributes.get("fallbackFactory")); - definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE); - - String alias = name + "FeignClient"; - AbstractBeanDefinition beanDefinition = definition.getBeanDefinition(); - - boolean primary = (Boolean)attributes.get("primary"); // has a default, won't be null - - beanDefinition.setPrimary(primary); - - String qualifier = getQualifier(attributes); - if (StringUtils.hasText(qualifier)) { - alias = qualifier; - } - - BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className, - new String[] { alias }); - BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry); - } - - private void validate(Map attributes) { - AnnotationAttributes annotation = AnnotationAttributes.fromMap(attributes); - // This blows up if an aliased property is overspecified - // FIXME annotation.getAliasedString("name", FeignClient.class, null); - Assert.isTrue( - !annotation.getClass("fallback").isInterface(), - "Fallback class must implement the interface annotated by @FeignClient" - ); - Assert.isTrue( - !annotation.getClass("fallbackFactory").isInterface(), - "Fallback factory must produce instances of fallback classes that implement the interface annotated by @FeignClient" - ); - } - - /* for testing */ String getName(Map attributes) { - String name = (String) attributes.get("serviceId"); - if (!StringUtils.hasText(name)) { - name = (String) attributes.get("name"); - } - if (!StringUtils.hasText(name)) { - name = (String) attributes.get("value"); - } - name = resolve(name); - if (!StringUtils.hasText(name)) { - return ""; - } - - String host = null; - try { - String url; - if (!name.startsWith("http://") && !name.startsWith("https://")) { - url = "http://" + name; - } else { - url = name; - } - host = new URI(url).getHost(); - - } - catch (URISyntaxException e) { - } - Assert.state(host != null, "Service id not legal hostname (" + name + ")"); - return name; - } - - private String resolve(String value) { - if (StringUtils.hasText(value)) { - return this.environment.resolvePlaceholders(value); - } - return value; - } - - private String getUrl(Map attributes) { - String url = resolve((String) attributes.get("url")); - if (StringUtils.hasText(url) && !(url.startsWith("#{") && url.contains("}"))) { - if (!url.contains("://")) { - url = "http://" + url; - } - try { - new URL(url); - } - catch (MalformedURLException e) { - throw new IllegalArgumentException(url + " is malformed", e); - } - } - return url; - } - - private String getPath(Map attributes) { - String path = resolve((String) attributes.get("path")); - if (StringUtils.hasText(path)) { - path = path.trim(); - if (!path.startsWith("/")) { - path = "/" + path; - } - if (path.endsWith("/")) { - path = path.substring(0, path.length() - 1); - } - } - return path; - } - - protected ClassPathScanningCandidateComponentProvider getScanner() { - return new ClassPathScanningCandidateComponentProvider(false, this.environment) { - @Override - protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) { - boolean isCandidate = false; - if (beanDefinition.getMetadata().isIndependent()) { - if (!beanDefinition.getMetadata().isAnnotation()) { - isCandidate = true; - } - } - return isCandidate; - } - }; - } - - protected Set getBasePackages(AnnotationMetadata importingClassMetadata) { - Map attributes = importingClassMetadata - .getAnnotationAttributes(EnableFeignClients.class.getCanonicalName()); - - Set basePackages = new HashSet<>(); - for (String pkg : (String[]) attributes.get("value")) { - if (StringUtils.hasText(pkg)) { - basePackages.add(pkg); - } - } - for (String pkg : (String[]) attributes.get("basePackages")) { - if (StringUtils.hasText(pkg)) { - basePackages.add(pkg); - } - } - for (Class clazz : (Class[]) attributes.get("basePackageClasses")) { - basePackages.add(ClassUtils.getPackageName(clazz)); - } - - if (basePackages.isEmpty()) { - basePackages.add( - ClassUtils.getPackageName(importingClassMetadata.getClassName())); - } - return basePackages; - } - - private String getQualifier(Map client) { - if (client == null) { - return null; - } - String qualifier = (String) client.get("qualifier"); - if (StringUtils.hasText(qualifier)) { - return qualifier; - } - return null; - } - - private String getClientName(Map client) { - if (client == null) { - return null; - } - String value = (String) client.get("value"); - if (!StringUtils.hasText(value)) { - value = (String) client.get("name"); - } - if (!StringUtils.hasText(value)) { - value = (String) client.get("serviceId"); - } - if (StringUtils.hasText(value)) { - return value; - } - - throw new IllegalStateException("Either 'name' or 'value' must be provided in @" - + FeignClient.class.getSimpleName()); - } - - private void registerClientConfiguration(BeanDefinitionRegistry registry, Object name, - Object configuration) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder - .genericBeanDefinition(FeignClientSpecification.class); - builder.addConstructorArgValue(name); - builder.addConstructorArgValue(configuration); - registry.registerBeanDefinition( - name + "." + FeignClientSpecification.class.getSimpleName(), - builder.getBeanDefinition()); - } - - @Override - public void setEnvironment(Environment environment) { - this.environment = environment; - } - - /** - * Helper class to create a {@link TypeFilter} that matches if all the delegates - * match. - * - * @author Oliver Gierke - */ - private static class AllTypeFilter implements TypeFilter { - - private final List delegates; - - /** - * Creates a new {@link AllTypeFilter} to match if all the given delegates match. - * - * @param delegates must not be {@literal null}. - */ - public AllTypeFilter(List delegates) { - Assert.notNull(delegates, "This argument is required, it must not be null"); - this.delegates = delegates; - } - - @Override - public boolean match(MetadataReader metadataReader, - MetadataReaderFactory metadataReaderFactory) throws IOException { - - for (TypeFilter filter : this.delegates) { - if (!filter.match(metadataReader, metadataReaderFactory)) { - return false; - } - } - - return true; - } - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignContext.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignContext.java deleted file mode 100644 index 1c9f0cd9d..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignContext.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2013-2015 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.feign; - -import org.springframework.cloud.context.named.NamedContextFactory; - -/** - * A factory that creates instances of feign classes. It creates a Spring - * ApplicationContext per client name, and extracts the beans that it needs from there. - * - * @author Spencer Gibb - * @author Dave Syer - */ -public class FeignContext extends NamedContextFactory { - - public FeignContext() { - super(FeignClientsConfiguration.class, "feign", "feign.client.name"); - } - -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignFormatterRegistrar.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignFormatterRegistrar.java deleted file mode 100644 index 0a6f0e93d..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignFormatterRegistrar.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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. - */ - -package org.springframework.cloud.netflix.feign; - -import org.springframework.format.FormatterRegistrar; -import org.springframework.format.support.FormattingConversionService; - -/** - * Allows an application to customize the Feign {@link FormattingConversionService}. - * - * @author Matt Benson - */ -public interface FeignFormatterRegistrar extends FormatterRegistrar { - -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignLoggerFactory.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignLoggerFactory.java deleted file mode 100644 index 9440fdf0d..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignLoggerFactory.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 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. - */ - -package org.springframework.cloud.netflix.feign; - -import feign.Logger; - -/** - * Allows an application to use a custom Feign {@link Logger}. - * - * @author Venil Noronha - */ -public interface FeignLoggerFactory { - - /** - * Factory method to provide a {@link Logger} for a given {@link Class}. - * - * @param type the {@link Class} for which a {@link Logger} instance is to be created - * @return a {@link Logger} instance - */ - public Logger create(Class type); - -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/HystrixTargeter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/HystrixTargeter.java deleted file mode 100644 index cfbe3659c..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/HystrixTargeter.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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. - * - */ - -package org.springframework.cloud.netflix.feign; - -import org.springframework.util.Assert; - -import feign.Feign; -import feign.Target; -import feign.hystrix.FallbackFactory; -import feign.hystrix.HystrixFeign; -import feign.hystrix.SetterFactory; - -/** - * @author Spencer Gibb - * @author Erik Kringen - */ -@SuppressWarnings("unchecked") -class HystrixTargeter implements Targeter { - - @Override - public T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context, - Target.HardCodedTarget target) { - if (!(feign instanceof feign.hystrix.HystrixFeign.Builder)) { - return feign.target(target); - } - feign.hystrix.HystrixFeign.Builder builder = (feign.hystrix.HystrixFeign.Builder) feign; - SetterFactory setterFactory = getOptional(factory.getName(), context, - SetterFactory.class); - if (setterFactory != null) { - builder.setterFactory(setterFactory); - } - Class fallback = factory.getFallback(); - if (fallback != void.class) { - return targetWithFallback(factory.getName(), context, target, builder, fallback); - } - Class fallbackFactory = factory.getFallbackFactory(); - if (fallbackFactory != void.class) { - return targetWithFallbackFactory(factory.getName(), context, target, builder, fallbackFactory); - } - - return feign.target(target); - } - - private T targetWithFallbackFactory(String feignClientName, FeignContext context, - Target.HardCodedTarget target, - HystrixFeign.Builder builder, - Class fallbackFactoryClass) { - FallbackFactory fallbackFactory = (FallbackFactory) - getFromContext("fallbackFactory", feignClientName, context, fallbackFactoryClass, FallbackFactory.class); - /* We take a sample fallback from the fallback factory to check if it returns a fallback - that is compatible with the annotated feign interface. */ - Object exampleFallback = fallbackFactory.create(new RuntimeException()); - Assert.notNull(exampleFallback, - String.format( - "Incompatible fallbackFactory instance for feign client %s. Factory may not produce null!", - feignClientName)); - if (!target.type().isAssignableFrom(exampleFallback.getClass())) { - throw new IllegalStateException( - String.format( - "Incompatible fallbackFactory instance for feign client %s. Factory produces instances of '%s', but should produce instances of '%s'", - feignClientName, exampleFallback.getClass(), target.type())); - } - return builder.target(target, fallbackFactory); - } - - - private T targetWithFallback(String feignClientName, FeignContext context, - Target.HardCodedTarget target, - HystrixFeign.Builder builder, Class fallback) { - T fallbackInstance = getFromContext("fallback", feignClientName, context, fallback, target.type()); - return builder.target(target, fallbackInstance); - } - - private T getFromContext(String fallbackMechanism, String feignClientName, FeignContext context, - Class beanType, Class targetType) { - Object fallbackInstance = context.getInstance(feignClientName, beanType); - if (fallbackInstance == null) { - throw new IllegalStateException(String.format( - "No " + fallbackMechanism + " instance of type %s found for feign client %s", - beanType, feignClientName)); - } - - if (!targetType.isAssignableFrom(beanType)) { - throw new IllegalStateException( - String.format( - "Incompatible " + fallbackMechanism + " instance. Fallback/fallbackFactory of type %s is not assignable to %s for feign client %s", - beanType, targetType, feignClientName)); - } - return (T) fallbackInstance; - } - - private T getOptional(String feignClientName, FeignContext context, - Class beanType) { - return context.getInstance(feignClientName, beanType); - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/Targeter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/Targeter.java deleted file mode 100644 index 3ebd9a864..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/Targeter.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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. - * - */ - -package org.springframework.cloud.netflix.feign; - -import feign.Feign; -import feign.Target; - -/** - * @author Spencer Gibb - */ -interface Targeter { - T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context, - Target.HardCodedTarget target); -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/annotation/PathVariableParameterProcessor.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/annotation/PathVariableParameterProcessor.java deleted file mode 100644 index c1dba1c9f..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/annotation/PathVariableParameterProcessor.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.annotation; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.Map; - -import org.springframework.cloud.netflix.feign.AnnotatedParameterProcessor; -import org.springframework.web.bind.annotation.PathVariable; - -import feign.MethodMetadata; - -import static feign.Util.checkState; -import static feign.Util.emptyToNull; - -/** - * {@link PathVariable} parameter processor. - * - * @author Jakub Narloch - * @author Abhijit Sarkar - * @see AnnotatedParameterProcessor - */ -public class PathVariableParameterProcessor implements AnnotatedParameterProcessor { - - private static final Class ANNOTATION = PathVariable.class; - - @Override - public Class getAnnotationType() { - return ANNOTATION; - } - - @Override - public boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method) { - String name = ANNOTATION.cast(annotation).value(); - checkState(emptyToNull(name) != null, - "PathVariable annotation was empty on param %s.", context.getParameterIndex()); - context.setParameterName(name); - - MethodMetadata data = context.getMethodMetadata(); - String varName = '{' + name + '}'; - if (!data.template().url().contains(varName) - && !searchMapValues(data.template().queries(), varName) - && !searchMapValues(data.template().headers(), varName)) { - data.formParams().add(name); - } - return true; - } - - private boolean searchMapValues(Map> map, V search) { - Collection> values = map.values(); - if (values == null) { - return false; - } - for (Collection entry : values) { - if (entry.contains(search)) { - return true; - } - } - return false; - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/annotation/RequestHeaderParameterProcessor.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/annotation/RequestHeaderParameterProcessor.java deleted file mode 100644 index 111bf00f9..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/annotation/RequestHeaderParameterProcessor.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.annotation; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.Map; - -import org.springframework.cloud.netflix.feign.AnnotatedParameterProcessor; -import org.springframework.web.bind.annotation.RequestHeader; - -import feign.MethodMetadata; - -import static feign.Util.checkState; -import static feign.Util.emptyToNull; - -/** - * {@link RequestHeader} parameter processor. - * - * @author Jakub Narloch - * @author Abhijit Sarkar - * @see AnnotatedParameterProcessor - */ -public class RequestHeaderParameterProcessor implements AnnotatedParameterProcessor { - - private static final Class ANNOTATION = RequestHeader.class; - - @Override - public Class getAnnotationType() { - return ANNOTATION; - } - - @Override - public boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method) { - int parameterIndex = context.getParameterIndex(); - Class parameterType = method.getParameterTypes()[parameterIndex]; - MethodMetadata data = context.getMethodMetadata(); - - if (Map.class.isAssignableFrom(parameterType)) { - checkState(data.headerMapIndex() == null, "Header map can only be present once."); - data.headerMapIndex(parameterIndex); - - return true; - } - - String name = ANNOTATION.cast(annotation).value(); - checkState(emptyToNull(name) != null, - "RequestHeader.value() was empty on parameter %s", parameterIndex); - context.setParameterName(name); - - Collection header = context.setTemplateParameter(name, data.template().headers().get(name)); - data.template().header(name, header); - return true; - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/annotation/RequestParamParameterProcessor.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/annotation/RequestParamParameterProcessor.java deleted file mode 100644 index ba996ac27..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/annotation/RequestParamParameterProcessor.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.annotation; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.Map; - -import org.springframework.cloud.netflix.feign.AnnotatedParameterProcessor; -import org.springframework.web.bind.annotation.RequestParam; - -import static feign.Util.checkState; -import static feign.Util.emptyToNull; - -import feign.MethodMetadata; - -/** - * {@link RequestParam} parameter processor. - * - * @author Jakub Narloch - * @author Abhijit Sarkar - * @see AnnotatedParameterProcessor - */ -public class RequestParamParameterProcessor implements AnnotatedParameterProcessor { - - private static final Class ANNOTATION = RequestParam.class; - - @Override - public Class getAnnotationType() { - return ANNOTATION; - } - - @Override - public boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method) { - int parameterIndex = context.getParameterIndex(); - Class parameterType = method.getParameterTypes()[parameterIndex]; - MethodMetadata data = context.getMethodMetadata(); - - if (Map.class.isAssignableFrom(parameterType)) { - checkState(data.queryMapIndex() == null, "Query map can only be present once."); - data.queryMapIndex(parameterIndex); - - return true; - } - - RequestParam requestParam = ANNOTATION.cast(annotation); - String name = requestParam.value(); - checkState(emptyToNull(name) != null, - "RequestParam.value() was empty on parameter %s", - parameterIndex); - context.setParameterName(name); - - Collection query = context.setTemplateParameter(name, - data.template().queries().get(name)); - data.template().query(name, query); - return true; - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/BaseRequestInterceptor.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/BaseRequestInterceptor.java deleted file mode 100644 index f7d49ff5f..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/BaseRequestInterceptor.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.feign.encoding; - -import feign.RequestInterceptor; -import feign.RequestTemplate; -import org.springframework.util.Assert; - -/** - * The base request interceptor. - * - * @author Jakub Narloch - */ -public abstract class BaseRequestInterceptor implements RequestInterceptor { - - /** - * 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; - } - - /** - * 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); - } - } - - protected FeignClientEncodingProperties getProperties() { - return properties; - } - -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignAcceptGzipEncodingAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignAcceptGzipEncodingAutoConfiguration.java deleted file mode 100644 index 9095c7ac0..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignAcceptGzipEncodingAutoConfiguration.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.feign.encoding; - -import feign.Client; -import feign.Feign; -import okhttp3.OkHttpClient; - -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.netflix.feign.FeignAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Configures the Feign response compression. - * - * @author Jakub Narloch - * @see FeignAcceptGzipEncodingInterceptor - */ -@Configuration -@EnableConfigurationProperties(FeignClientEncodingProperties.class) -@ConditionalOnClass(Feign.class) -@ConditionalOnBean(Client.class) -@ConditionalOnProperty(value = "feign.compression.response.enabled", matchIfMissing = false) -//The OK HTTP client uses "transparent" compression. -//If the accept-encoding header is present it disable transparent compression -@ConditionalOnMissingBean(OkHttpClient.class) -@AutoConfigureAfter(FeignAutoConfiguration.class) -public class FeignAcceptGzipEncodingAutoConfiguration { - - @Bean - public FeignAcceptGzipEncodingInterceptor feignAcceptGzipEncodingInterceptor(FeignClientEncodingProperties properties) { - return new FeignAcceptGzipEncodingInterceptor(properties); - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignAcceptGzipEncodingInterceptor.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignAcceptGzipEncodingInterceptor.java deleted file mode 100644 index 868837a5b..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignAcceptGzipEncodingInterceptor.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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.feign.encoding; - -import feign.RequestTemplate; - -/** - * Enables the HTTP response payload compression by specifying the {@code Accept-Encoding} headers. - * Although this does not yet mean that the requests will be compressed, it requires the remote server - * to understand the header and be configured to compress responses. Still no all responses might be compressed - * based on the media type matching and other factors like the response content length. - * - * @author Jakub Narloch - */ -public class FeignAcceptGzipEncodingInterceptor extends BaseRequestInterceptor { - - /** - * Creates new instance of {@link FeignAcceptGzipEncodingInterceptor}. - * - * @param properties the encoding properties - */ - protected FeignAcceptGzipEncodingInterceptor(FeignClientEncodingProperties properties) { - super(properties); - } - - /** - * {@inheritDoc} - */ - @Override - public void apply(RequestTemplate template) { - - addHeader(template, HttpEncoding.ACCEPT_ENCODING_HEADER, HttpEncoding.GZIP_ENCODING, - HttpEncoding.DEFLATE_ENCODING); - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignClientEncodingProperties.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignClientEncodingProperties.java deleted file mode 100644 index 7d3733cc6..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignClientEncodingProperties.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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.feign.encoding; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -import java.util.Arrays; -import java.util.Objects; - -/** - * The Feign encoding properties. - * - * @author Jakub Narloch - */ -@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 minimum threshold content size. - */ - private int minRequestSize = 2048; - - public String[] getMimeTypes() { - return mimeTypes; - } - - public void setMimeTypes(String[] mimeTypes) { - this.mimeTypes = mimeTypes; - } - - public int getMinRequestSize() { - return 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 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(); - } - -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignContentGzipEncodingAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignContentGzipEncodingAutoConfiguration.java deleted file mode 100644 index 21f67570e..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignContentGzipEncodingAutoConfiguration.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.feign.encoding; - -import feign.Client; -import feign.Feign; -import okhttp3.OkHttpClient; - -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.netflix.feign.FeignAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Configures the Feign request compression. - * - * @author Jakub Narloch - * @see FeignContentGzipEncodingInterceptor - */ -@Configuration -@EnableConfigurationProperties(FeignClientEncodingProperties.class) -@ConditionalOnClass(Feign.class) -@ConditionalOnBean(Client.class) -//The OK HTTP client uses "transparent" compression. -//If the content-encoding header is present it disable transparent compression -@ConditionalOnMissingBean(OkHttpClient.class) -@ConditionalOnProperty(value = "feign.compression.request.enabled", matchIfMissing = false) -@AutoConfigureAfter(FeignAutoConfiguration.class) -public class FeignContentGzipEncodingAutoConfiguration { - - @Bean - public FeignContentGzipEncodingInterceptor feignContentGzipEncodingInterceptor(FeignClientEncodingProperties properties) { - return new FeignContentGzipEncodingInterceptor(properties); - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignContentGzipEncodingInterceptor.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignContentGzipEncodingInterceptor.java deleted file mode 100644 index fae897b91..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/FeignContentGzipEncodingInterceptor.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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.feign.encoding; - -import feign.RequestTemplate; - -import java.util.Collection; -import java.util.Map; - -/** - * Enables the HTTP request payload compression by specifying the {@code Content-Encoding} headers. - * - * @author Jakub Narloch - */ -public class FeignContentGzipEncodingInterceptor extends BaseRequestInterceptor { - - /** - * Creates new instance of {@link FeignContentGzipEncodingInterceptor}. - * - * @param properties the encoding properties - */ - protected FeignContentGzipEncodingInterceptor(FeignClientEncodingProperties properties) { - super(properties); - } - - /** - * {@inheritDoc} - */ - @Override - public void apply(RequestTemplate template) { - - 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) { - - final Map> 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 contentLength) { - - 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; - } - - /** - * 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 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; - } - - for (String mimeType : getProperties().getMimeTypes()) { - if (contentTypes.contains(mimeType)) { - return true; - } - } - - return false; - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/HttpEncoding.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/HttpEncoding.java deleted file mode 100644 index 378b50a7e..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/encoding/HttpEncoding.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.feign.encoding; - -/** - * Lists all constants used by Feign encoders. - * - * @author Jakub Narloch - */ -public interface HttpEncoding { - - /** - * The HTTP Content-Length header. - */ - String CONTENT_LENGTH = "Content-Length"; - - /** - * The HTTP Content-Type header. - */ - String CONTENT_TYPE = "Content-Type"; - - /** - * The HTTP Accept-Encoding header. - */ - String ACCEPT_ENCODING_HEADER = "Accept-Encoding"; - - /** - * The HTTP Content-Encoding header. - */ - String CONTENT_ENCODING_HEADER = "Content-Encoding"; - - /** - * The GZIP encoding. - */ - String GZIP_ENCODING = "gzip"; - - /** - * The Deflate encoding. - */ - String DEFLATE_ENCODING = "deflate"; -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/CachingSpringLoadBalancerFactory.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/CachingSpringLoadBalancerFactory.java deleted file mode 100644 index 3bb051ced..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/CachingSpringLoadBalancerFactory.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.ribbon; - -import java.util.Map; - -import org.springframework.cloud.client.loadbalancer.LoadBalancedBackOffPolicyFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryListenerFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicyFactory; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.util.ConcurrentReferenceHashMap; - -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; - -/** - * Factory for SpringLoadBalancer instances that caches the entries created. - * - * @author Spencer Gibb - * @author Dave Syer - * @author Ryan Baxter - * @author Gang Li - */ -public class CachingSpringLoadBalancerFactory { - - private final SpringClientFactory factory; - private final LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory; - private final LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory; - private final LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory; - private boolean enableRetry = false; - - private volatile Map cache = new ConcurrentReferenceHashMap<>(); - - public CachingSpringLoadBalancerFactory(SpringClientFactory factory) { - this.factory = factory; - this.loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(factory); - this.loadBalancedBackOffPolicyFactory = null; - this.loadBalancedRetryListenerFactory = null; - } - - @Deprecated - //TODO remove in 2.0.x - public CachingSpringLoadBalancerFactory(SpringClientFactory factory, - LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) { - this.factory = factory; - this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory; - this.loadBalancedBackOffPolicyFactory = null; - this.loadBalancedRetryListenerFactory = null; - } - - @Deprecated - //TODO remove in 2.0.0x - public CachingSpringLoadBalancerFactory(SpringClientFactory factory, - LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory, boolean enableRetry) { - this.factory = factory; - this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory; - this.enableRetry = enableRetry; - this.loadBalancedBackOffPolicyFactory = null; - this.loadBalancedRetryListenerFactory = null; - } - - @Deprecated - //TODO remove in 2.0.0x - public CachingSpringLoadBalancerFactory(SpringClientFactory factory, - LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory, - LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory) { - this.factory = factory; - this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory; - this.loadBalancedBackOffPolicyFactory = loadBalancedBackOffPolicyFactory; - this.loadBalancedRetryListenerFactory = null; - this.enableRetry = true; - } - - public CachingSpringLoadBalancerFactory(SpringClientFactory factory, LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory, - LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory, - LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory) { - this.factory = factory; - this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory; - this.loadBalancedBackOffPolicyFactory = loadBalancedBackOffPolicyFactory; - this.loadBalancedRetryListenerFactory = loadBalancedRetryListenerFactory; - this.enableRetry = true; - } - - public FeignLoadBalancer create(String clientName) { - if (this.cache.containsKey(clientName)) { - return this.cache.get(clientName); - } - IClientConfig config = this.factory.getClientConfig(clientName); - ILoadBalancer lb = this.factory.getLoadBalancer(clientName); - ServerIntrospector serverIntrospector = this.factory.getInstance(clientName, ServerIntrospector.class); - FeignLoadBalancer client = enableRetry ? new RetryableFeignLoadBalancer(lb, config, serverIntrospector, - loadBalancedRetryPolicyFactory, loadBalancedBackOffPolicyFactory, loadBalancedRetryListenerFactory) : new FeignLoadBalancer(lb, config, serverIntrospector); - this.cache.put(clientName, client); - return client; - } - -} \ No newline at end of file diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/DefaultFeignLoadBalancedConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/DefaultFeignLoadBalancedConfiguration.java deleted file mode 100644 index 1098ea0b3..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/DefaultFeignLoadBalancedConfiguration.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.feign.ribbon; - -import feign.Client; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - */ -@Configuration -class DefaultFeignLoadBalancedConfiguration { - @Bean - @ConditionalOnMissingBean - public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, - SpringClientFactory clientFactory) { - return new LoadBalancerFeignClient(new Client.Default(null, null), - cachingFactory, clientFactory); - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignLoadBalancer.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignLoadBalancer.java deleted file mode 100644 index 4fab93f1b..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignLoadBalancer.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2015 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.feign.ribbon; - -import feign.Client; -import feign.Request; -import feign.Response; - -import java.io.IOException; -import java.net.URI; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.cloud.netflix.ribbon.RibbonProperties; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpRequest; -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.ClientException; -import com.netflix.client.ClientRequest; -import com.netflix.client.IResponse; -import com.netflix.client.RequestSpecificRetryHandler; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.Server; - -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToSecureConnectionIfNeeded; - -/** - * @author Dave Syer - * @author Spencer Gibb - * @author Ryan Baxter - * @author Tim Ysewyn - */ -public class FeignLoadBalancer extends - AbstractLoadBalancerAwareClient { - - private final RibbonProperties ribbon; - protected int connectTimeout; - protected int readTimeout; - protected IClientConfig clientConfig; - protected ServerIntrospector serverIntrospector; - - public FeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig, - ServerIntrospector serverIntrospector) { - super(lb, clientConfig); - this.setRetryHandler(RetryHandler.DEFAULT); - this.clientConfig = clientConfig; - this.ribbon = RibbonProperties.from(clientConfig); - RibbonProperties ribbon = this.ribbon; - this.connectTimeout = ribbon.getConnectTimeout(); - this.readTimeout = ribbon.getReadTimeout(); - this.serverIntrospector = serverIntrospector; - } - - @Override - public RibbonResponse execute(RibbonRequest request, IClientConfig configOverride) - throws IOException { - Request.Options options; - if (configOverride != null) { - RibbonProperties override = RibbonProperties.from(configOverride); - options = new Request.Options( - override.connectTimeout(this.connectTimeout), - override.readTimeout(this.readTimeout)); - } - else { - options = new Request.Options(this.connectTimeout, this.readTimeout); - } - Response response = request.client().execute(request.toRequest(), options); - return new RibbonResponse(request.getUri(), response); - } - - @Override - public RequestSpecificRetryHandler getRequestSpecificRetryHandler( - RibbonRequest request, IClientConfig requestConfig) { - if (this.ribbon.isOkToRetryOnAllOperations()) { - return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(), - requestConfig); - } - if (!request.toRequest().method().equals("GET")) { - return new RequestSpecificRetryHandler(true, false, this.getRetryHandler(), - requestConfig); - } - else { - return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(), - requestConfig); - } - } - - @Override - public URI reconstructURIWithServer(Server server, URI original) { - URI uri = updateToSecureConnectionIfNeeded(original, this.clientConfig, this.serverIntrospector, server); - return super.reconstructURIWithServer(server, uri); - } - - protected static class RibbonRequest extends ClientRequest implements Cloneable { - - private final Request request; - private final Client client; - - RibbonRequest(Client client, Request request, URI uri) { - this.client = client; - setUri(uri); - this.request = toRequest(request); - } - - private Request toRequest(Request request) { - Map> headers = new LinkedHashMap<>( - request.headers()); - return Request.create(request.method(),getUri().toASCIIString(),headers,request.body(),request.charset()); - } - - Request toRequest() { - return toRequest(this.request); - } - - Client client() { - return this.client; - } - - HttpRequest toHttpRequest() { - return new HttpRequest() { - @Override - public HttpMethod getMethod() { - return HttpMethod.resolve(RibbonRequest.this.toRequest().method()); - } - - @Override - public String getMethodValue() { - return getMethod().name(); - } - - @Override - public URI getURI() { - return RibbonRequest.this.getUri(); - } - - @Override - public HttpHeaders getHeaders() { - Map> headers = new HashMap<>(); - Map> feignHeaders = RibbonRequest.this.toRequest().headers(); - for(String key : feignHeaders.keySet()) { - headers.put(key, new ArrayList(feignHeaders.get(key))); - } - HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.putAll(headers); - return httpHeaders; - - } - }; - } - - - @Override - public Object clone() { - return new RibbonRequest(this.client, this.request, getUri()); - } - } - - protected static class RibbonResponse implements IResponse { - - private final URI uri; - private final Response response; - - RibbonResponse(URI uri, Response response) { - this.uri = uri; - this.response = response; - } - - @Override - public Object getPayload() throws ClientException { - return this.response.body(); - } - - @Override - public boolean hasPayload() { - return this.response.body() != null; - } - - @Override - public boolean isSuccess() { - return this.response.status() == 200; - } - - @Override - public URI getRequestedURI() { - return this.uri; - } - - @Override - public Map> getHeaders() { - return this.response.headers(); - } - - Response toResponse() { - return this.response; - } - - @Override - public void close() throws IOException { - if (this.response != null && this.response.body() != null) { - this.response.body().close(); - } - } - - } - -} \ No newline at end of file diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignRetryPolicy.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignRetryPolicy.java deleted file mode 100644 index f78d52fa1..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignRetryPolicy.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * - * * 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. - * - */ - -package org.springframework.cloud.netflix.feign.ribbon; - -import java.net.URI; -import java.util.HashMap; -import java.util.Map; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.InterceptorRetryPolicy; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.http.HttpRequest; -import org.springframework.retry.RetryContext; - -/** - * @author Ryan Baxter - */ -public class FeignRetryPolicy extends InterceptorRetryPolicy { - private HttpRequest request; - private String serviceId; - public FeignRetryPolicy(HttpRequest request, LoadBalancedRetryPolicy policy, ServiceInstanceChooser serviceInstanceChooser, String serviceName) { - super(request, policy, serviceInstanceChooser, serviceName); - this.request = request; - this.serviceId = serviceName; - } - - @Override - public boolean canRetry(RetryContext context) { - /* - * In InterceptorRetryPolicy.canRetry we ask the LoadBalancer to choose a server if one is not - * set in the retry context and then return true. RetryTemplat calls the canRetry method of - * the policy even on its first execution. So the fact that we didnt have a service instance set - * in the RetryContext signaled that it was the first execution and we should return true. - * - * In the Feign scenario, Feign as actually already queried the load balancer for a service instance - * and we set that service instance in the context when we call the open method of the policy. So in - * the Feign case we just return true if the retry count is 0 indicating we haven't yet made a failed - * request. - */ - if(context.getRetryCount() == 0) { - return true; - } - return super.canRetry(context); - } - - @Override - public RetryContext open(RetryContext parent) { - /* - * With Feign (unlike Ribbon) the request already has the URI for the service instance - * we are going to make the request to, so extract that information and set the service - * instance in the context. In the Ribbon scenario the URI in the request object still has - * the service id so we choose and set the service instance later on. - */ - LoadBalancedRetryContext context = new LoadBalancedRetryContext(parent, this.request); - context.setServiceInstance(new FeignRetryPolicyServiceInstance(serviceId, request)); - return context; - } - - class FeignRetryPolicyServiceInstance implements ServiceInstance { - - private String serviceId; - private HttpRequest request; - private Map metadata; - - FeignRetryPolicyServiceInstance(String serviceId, HttpRequest request) { - this.serviceId = serviceId; - this.request = request; - this.metadata = new HashMap<>(); - } - - @Override - public String getServiceId() { - return serviceId; - } - - @Override - public String getHost() { - return request.getURI().getHost(); - } - - @Override - public int getPort() { - return request.getURI().getPort(); - } - - @Override - public boolean isSecure() { - return "https".equals(request.getURI().getScheme()); - } - - @Override - public URI getUri() { - return request.getURI(); - } - - @Override - public Map getMetadata() { - return metadata; - } - } -} \ No newline at end of file diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientAutoConfiguration.java deleted file mode 100644 index d89814426..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientAutoConfiguration.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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.feign.ribbon; - -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.loadbalancer.LoadBalancedBackOffPolicyFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryListenerFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory; -import org.springframework.cloud.netflix.feign.FeignAutoConfiguration; -import org.springframework.cloud.netflix.feign.support.FeignHttpClientProperties; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Primary; - -import com.netflix.loadbalancer.ILoadBalancer; - -import feign.Feign; -import feign.Request; - -/** - * Autoconfiguration to be activated if Feign is in use and needs to be use Ribbon as a - * load balancer. - * - * @author Dave Syer - */ -@ConditionalOnClass({ ILoadBalancer.class, Feign.class }) -@Configuration -@AutoConfigureBefore(FeignAutoConfiguration.class) -@EnableConfigurationProperties({ FeignHttpClientProperties.class }) -//Order is important here, last should be the default, first should be optional -// see https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653 -@Import({ HttpClientFeignLoadBalancedConfiguration.class, - OkHttpFeignLoadBalancedConfiguration.class, - DefaultFeignLoadBalancedConfiguration.class }) -public class FeignRibbonClientAutoConfiguration { - - @Bean - @Primary - @ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate") - public CachingSpringLoadBalancerFactory cachingLBClientFactory( - SpringClientFactory factory) { - return new CachingSpringLoadBalancerFactory(factory); - } - - @Bean - @Primary - @ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate") - public CachingSpringLoadBalancerFactory retryabeCachingLBClientFactory( - SpringClientFactory factory, - LoadBalancedRetryPolicyFactory retryPolicyFactory, - LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory, - LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory) { - return new CachingSpringLoadBalancerFactory(factory, retryPolicyFactory, loadBalancedBackOffPolicyFactory, loadBalancedRetryListenerFactory); - } - - @Bean - @ConditionalOnMissingBean - public Request.Options feignRequestOptions() { - return LoadBalancerFeignClient.DEFAULT_OPTIONS; - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/HttpClientFeignLoadBalancedConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/HttpClientFeignLoadBalancedConfiguration.java deleted file mode 100644 index a5e305f94..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/HttpClientFeignLoadBalancedConfiguration.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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.feign.ribbon; - -import feign.Client; -import feign.httpclient.ApacheHttpClient; - -import java.util.Timer; -import java.util.TimerTask; -import javax.annotation.PreDestroy; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.config.RegistryBuilder; -import org.apache.http.conn.HttpClientConnectionManager; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; -import org.springframework.cloud.netflix.feign.support.FeignHttpClientProperties; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - */ -@Configuration -@ConditionalOnClass(ApacheHttpClient.class) -@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true) -class HttpClientFeignLoadBalancedConfiguration { - - @Configuration - @ConditionalOnMissingBean(CloseableHttpClient.class) - protected static class HttpClientFeignConfiguration { - private final Timer connectionManagerTimer = new Timer( - "FeignApacheHttpClientConfiguration.connectionManagerTimer", true); - - private CloseableHttpClient httpClient; - - @Autowired(required = false) - private RegistryBuilder registryBuilder; - - @Bean - @ConditionalOnMissingBean(HttpClientConnectionManager.class) - public HttpClientConnectionManager connectionManager( - ApacheHttpClientConnectionManagerFactory connectionManagerFactory, - FeignHttpClientProperties httpClientProperties) { - final HttpClientConnectionManager connectionManager = connectionManagerFactory - .newConnectionManager(httpClientProperties.isDisableSslValidation(), httpClientProperties.getMaxConnections(), - httpClientProperties.getMaxConnectionsPerRoute(), - httpClientProperties.getTimeToLive(), - httpClientProperties.getTimeToLiveUnit(), registryBuilder); - this.connectionManagerTimer.schedule(new TimerTask() { - @Override - public void run() { - connectionManager.closeExpiredConnections(); - } - }, 30000, httpClientProperties.getConnectionTimerRepeat()); - return connectionManager; - } - - @Bean - @ConditionalOnProperty(value = "feign.compression.response.enabled", havingValue = "true") - public CloseableHttpClient customHttpClient(HttpClientConnectionManager httpClientConnectionManager, - FeignHttpClientProperties httpClientProperties) { - HttpClientBuilder builder = HttpClientBuilder.create().disableCookieManagement().useSystemProperties(); - this.httpClient = createClient(builder, httpClientConnectionManager, httpClientProperties); - return this.httpClient; - } - - @Bean - @ConditionalOnProperty(value = "feign.compression.response.enabled", havingValue = "false", matchIfMissing = true) - public CloseableHttpClient httpClient(ApacheHttpClientFactory httpClientFactory, HttpClientConnectionManager httpClientConnectionManager, - FeignHttpClientProperties httpClientProperties) { - this.httpClient = createClient(httpClientFactory.createBuilder(), httpClientConnectionManager, httpClientProperties); - return this.httpClient; - } - - private CloseableHttpClient createClient(HttpClientBuilder builder, HttpClientConnectionManager httpClientConnectionManager, - FeignHttpClientProperties httpClientProperties) { - RequestConfig defaultRequestConfig = RequestConfig.custom() - .setConnectTimeout(httpClientProperties.getConnectionTimeout()) - .setRedirectsEnabled(httpClientProperties.isFollowRedirects()) - .build(); - CloseableHttpClient httpClient = builder.setDefaultRequestConfig(defaultRequestConfig). - setConnectionManager(httpClientConnectionManager).build(); - return httpClient; - } - - @PreDestroy - public void destroy() throws Exception { - connectionManagerTimer.cancel(); - if(httpClient != null) { - httpClient.close(); - } - } - } - - - @Bean - @ConditionalOnMissingBean(Client.class) - public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, - SpringClientFactory clientFactory, HttpClient httpClient) { - ApacheHttpClient delegate = new ApacheHttpClient(httpClient); - return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory); - } - - -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/LoadBalancerFeignClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/LoadBalancerFeignClient.java deleted file mode 100644 index 37d7f662b..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/LoadBalancerFeignClient.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2015 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.feign.ribbon; - -import java.io.IOException; -import java.net.URI; - -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; - -import com.netflix.client.ClientException; -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; - -import feign.Client; -import feign.Request; -import feign.Response; - -/** - * @author Dave Syer - * - */ -public class LoadBalancerFeignClient implements Client { - - static final Request.Options DEFAULT_OPTIONS = new Request.Options(); - - private final Client delegate; - private CachingSpringLoadBalancerFactory lbClientFactory; - private SpringClientFactory clientFactory; - - public LoadBalancerFeignClient(Client delegate, - CachingSpringLoadBalancerFactory lbClientFactory, - SpringClientFactory clientFactory) { - this.delegate = delegate; - this.lbClientFactory = lbClientFactory; - this.clientFactory = clientFactory; - } - - @Override - public Response execute(Request request, Request.Options options) throws IOException { - try { - URI asUri = URI.create(request.url()); - String clientName = asUri.getHost(); - URI uriWithoutHost = cleanUrl(request.url(), clientName); - FeignLoadBalancer.RibbonRequest ribbonRequest = new FeignLoadBalancer.RibbonRequest( - this.delegate, request, uriWithoutHost); - - IClientConfig requestConfig = getClientConfig(options, clientName); - return lbClient(clientName).executeWithLoadBalancer(ribbonRequest, - requestConfig).toResponse(); - } - catch (ClientException e) { - IOException io = findIOException(e); - if (io != null) { - throw io; - } - throw new RuntimeException(e); - } - } - - IClientConfig getClientConfig(Request.Options options, String clientName) { - IClientConfig requestConfig; - if (options == DEFAULT_OPTIONS) { - requestConfig = this.clientFactory.getClientConfig(clientName); - } else { - requestConfig = new FeignOptionsClientConfig(options); - } - return requestConfig; - } - - protected IOException findIOException(Throwable t) { - if (t == null) { - return null; - } - if (t instanceof IOException) { - return (IOException) t; - } - return findIOException(t.getCause()); - } - - public Client getDelegate() { - return this.delegate; - } - - static URI cleanUrl(String originalUrl, String host) { - return URI.create(originalUrl.replaceFirst(host, "")); - } - - private FeignLoadBalancer lbClient(String clientName) { - return this.lbClientFactory.create(clientName); - } - - static class FeignOptionsClientConfig extends DefaultClientConfigImpl { - - public FeignOptionsClientConfig(Request.Options options) { - setProperty(CommonClientConfigKey.ConnectTimeout, - options.connectTimeoutMillis()); - setProperty(CommonClientConfigKey.ReadTimeout, options.readTimeoutMillis()); - } - - @Override - public void loadProperties(String clientName) { - - } - - @Override - public void loadDefaultValues() { - - } - - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/OkHttpFeignLoadBalancedConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/OkHttpFeignLoadBalancedConfiguration.java deleted file mode 100644 index 6a686f91e..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/OkHttpFeignLoadBalancedConfiguration.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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.feign.ribbon; - -import feign.Client; -import feign.okhttp.OkHttpClient; -import okhttp3.ConnectionPool; - -import java.util.concurrent.TimeUnit; -import javax.annotation.PreDestroy; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory; -import org.springframework.cloud.commons.httpclient.OkHttpClientFactory; -import org.springframework.cloud.netflix.feign.support.FeignHttpClientProperties; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - */ -@Configuration -@ConditionalOnClass(OkHttpClient.class) -@ConditionalOnProperty(value = "feign.okhttp.enabled") -class OkHttpFeignLoadBalancedConfiguration { - - @Configuration - @ConditionalOnMissingBean(okhttp3.OkHttpClient.class) - protected static class OkHttpFeignConfiguration { - private okhttp3.OkHttpClient okHttpClient; - - @Bean - @ConditionalOnMissingBean(ConnectionPool.class) - public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties, - OkHttpClientConnectionPoolFactory connectionPoolFactory) { - Integer maxTotalConnections = httpClientProperties.getMaxConnections(); - Long timeToLive = httpClientProperties.getTimeToLive(); - TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit(); - return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit); - } - - @Bean - public okhttp3.OkHttpClient client(OkHttpClientFactory httpClientFactory, - ConnectionPool connectionPool, FeignHttpClientProperties httpClientProperties) { - Boolean followRedirects = httpClientProperties.isFollowRedirects(); - Integer connectTimeout = httpClientProperties.getConnectionTimeout(); - this.okHttpClient = httpClientFactory.createBuilder(httpClientProperties.isDisableSslValidation()). - connectTimeout(connectTimeout, TimeUnit.MILLISECONDS). - followRedirects(followRedirects). - connectionPool(connectionPool).build(); - return this.okHttpClient; - } - - @PreDestroy - public void destroy() { - if(okHttpClient != null) { - okHttpClient.dispatcher().executorService().shutdown(); - okHttpClient.connectionPool().evictAll(); - } - } - } - - @Bean - @ConditionalOnMissingBean(Client.class) - public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, - SpringClientFactory clientFactory, okhttp3.OkHttpClient okHttpClient) { - OkHttpClient delegate = new OkHttpClient(okHttpClient); - return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory); - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/RetryableFeignLoadBalancer.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/RetryableFeignLoadBalancer.java deleted file mode 100644 index e3ed8b40a..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/RetryableFeignLoadBalancer.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * - * * 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. - * - */ - -package org.springframework.cloud.netflix.feign.ribbon; - -import feign.Request; -import feign.Response; - -import java.io.IOException; -import java.net.URI; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancedBackOffPolicyFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryListenerFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory; -import org.springframework.cloud.client.loadbalancer.RibbonRecoveryCallback; -import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient; -import org.springframework.cloud.netflix.ribbon.RibbonProperties; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.retry.RetryCallback; -import org.springframework.retry.RetryContext; -import org.springframework.retry.RetryListener; -import org.springframework.retry.backoff.BackOffPolicy; -import org.springframework.retry.backoff.NoBackOffPolicy; -import org.springframework.retry.policy.NeverRetryPolicy; -import org.springframework.retry.support.RetryTemplate; -import org.springframework.util.StreamUtils; -import com.netflix.client.DefaultLoadBalancerRetryHandler; -import com.netflix.client.RequestSpecificRetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.Server; - -/** - * A {@link FeignLoadBalancer} that leverages Spring Retry to retry failed requests. - * @author Ryan Baxter - * @author Gang Li - */ -public class RetryableFeignLoadBalancer extends FeignLoadBalancer implements ServiceInstanceChooser { - - private final LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory; - private final LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory; - private final LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory; - - @Deprecated - //TODO remove in 2.0.x - public RetryableFeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig, - ServerIntrospector serverIntrospector, LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) { - super(lb, clientConfig, serverIntrospector); - this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory; - this.setRetryHandler(new DefaultLoadBalancerRetryHandler(clientConfig)); - this.loadBalancedBackOffPolicyFactory = new LoadBalancedBackOffPolicyFactory.NoBackOffPolicyFactory(); - this.loadBalancedRetryListenerFactory = new LoadBalancedRetryListenerFactory.DefaultRetryListenerFactory(); - } - - @Deprecated - //TODO remove in 2.0.x - public RetryableFeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig, - ServerIntrospector serverIntrospector, LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory, - LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory) { - super(lb, clientConfig, serverIntrospector); - this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory; - this.setRetryHandler(new DefaultLoadBalancerRetryHandler(clientConfig)); - this.loadBalancedBackOffPolicyFactory = loadBalancedBackOffPolicyFactory == null ? - new LoadBalancedBackOffPolicyFactory.NoBackOffPolicyFactory() : loadBalancedBackOffPolicyFactory; - this.loadBalancedRetryListenerFactory = new LoadBalancedRetryListenerFactory.DefaultRetryListenerFactory(); - } - - public RetryableFeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig, ServerIntrospector serverIntrospector, - LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory, - LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory, - LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory) { - super(lb, clientConfig, serverIntrospector); - this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory; - this.setRetryHandler(new DefaultLoadBalancerRetryHandler(clientConfig)); - this.loadBalancedBackOffPolicyFactory = loadBalancedBackOffPolicyFactory == null ? - new LoadBalancedBackOffPolicyFactory.NoBackOffPolicyFactory() : loadBalancedBackOffPolicyFactory; - this.loadBalancedRetryListenerFactory = loadBalancedRetryListenerFactory == null ? - new LoadBalancedRetryListenerFactory.DefaultRetryListenerFactory() : loadBalancedRetryListenerFactory; - } - - @Override - public RibbonResponse execute(final RibbonRequest request, IClientConfig configOverride) - throws IOException { - final Request.Options options; - if (configOverride != null) { - RibbonProperties ribbon = RibbonProperties.from(configOverride); - options = new Request.Options( - ribbon.connectTimeout(this.connectTimeout), - ribbon.readTimeout(this.readTimeout)); - } - else { - options = new Request.Options(this.connectTimeout, this.readTimeout); - } - final LoadBalancedRetryPolicy retryPolicy = loadBalancedRetryPolicyFactory.create(this.getClientName(), this); - RetryTemplate retryTemplate = new RetryTemplate(); - BackOffPolicy backOffPolicy = loadBalancedBackOffPolicyFactory.createBackOffPolicy(this.getClientName()); - retryTemplate.setBackOffPolicy(backOffPolicy == null ? new NoBackOffPolicy() : backOffPolicy); - RetryListener[] retryListeners = this.loadBalancedRetryListenerFactory.createRetryListeners(this.getClientName()); - if (retryListeners != null && retryListeners.length != 0) { - retryTemplate.setListeners(retryListeners); - } - retryTemplate.setRetryPolicy(retryPolicy == null ? new NeverRetryPolicy() - : new FeignRetryPolicy(request.toHttpRequest(), retryPolicy, this, this.getClientName())); - return retryTemplate.execute(new RetryCallback() { - @Override - public RibbonResponse doWithRetry(RetryContext retryContext) throws IOException { - Request feignRequest = null; - //on retries the policy will choose the server and set it in the context - //extract the server and update the request being made - if (retryContext instanceof LoadBalancedRetryContext) { - ServiceInstance service = ((LoadBalancedRetryContext) retryContext).getServiceInstance(); - if (service != null) { - feignRequest = ((RibbonRequest) request.replaceUri(reconstructURIWithServer(new Server(service.getHost(), service.getPort()), request.getUri()))).toRequest(); - } - } - if (feignRequest == null) { - feignRequest = request.toRequest(); - } - Response response = request.client().execute(feignRequest, options); - if (retryPolicy.retryableStatusCode(response.status())) { - byte[] byteArray = StreamUtils.copyToByteArray(response.body().asInputStream()); - response.close(); - throw new RibbonResponseStatusCodeException(RetryableFeignLoadBalancer.this.clientName, response, - byteArray, request.getUri()); - } - return new RibbonResponse(request.getUri(), response); - } - }, new RibbonRecoveryCallback() { - @Override - protected RibbonResponse createResponse(Response response, URI uri) { - return new RibbonResponse(uri, response); - } - }); - } - - @Override - public RequestSpecificRetryHandler getRequestSpecificRetryHandler( - FeignLoadBalancer.RibbonRequest request, IClientConfig requestConfig) { - return new RequestSpecificRetryHandler(false, false, this.getRetryHandler(), requestConfig); - } - - @Override - public ServiceInstance choose(String serviceId) { - return new RibbonLoadBalancerClient.RibbonServer(serviceId, - this.getLoadBalancer().chooseServer(serviceId)); - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/RibbonResponseStatusCodeException.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/RibbonResponseStatusCodeException.java deleted file mode 100644 index 2c995b2bb..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/RibbonResponseStatusCodeException.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2013-2018 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.feign.ribbon; - -import feign.Response; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.net.URI; -import org.springframework.cloud.client.loadbalancer.RetryableStatusCodeException; -import org.springframework.util.StreamUtils; - -/** - * A {@link RetryableStatusCodeException} for {@link Response}s - * @author Ryan Baxter - */ -public class RibbonResponseStatusCodeException extends RetryableStatusCodeException { - private Response response; - - public RibbonResponseStatusCodeException(String serviceId, Response response, byte[] body, URI uri) { - super(serviceId, response.status(), response, uri); - this.response = Response.builder().body(new ByteArrayInputStream(body), body.length) - .headers(response.headers()).reason(response.reason()) - .status(response.status()).request(response.request()).build(); - } - - @Override - public Response getResponse() { - return response; - } - -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/FallbackCommand.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/FallbackCommand.java deleted file mode 100644 index 9bc030807..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/FallbackCommand.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.springframework.cloud.netflix.feign.support; - -import com.netflix.hystrix.HystrixCommand; -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixThreadPoolKey; - -/** - * Convenience class for implementing feign fallbacks that return {@link HystrixCommand}. - * Also useful for return types of {@link rx.Observable} and {@link java.util.concurrent.Future}. - * For those return types, just call {@link FallbackCommand#observe()} or {@link FallbackCommand#queue()} respectively. - * @author Spencer Gibb - */ -public class FallbackCommand extends HystrixCommand { - - private T result; - - public FallbackCommand(T result) { - this(result, "fallback"); - } - - protected FallbackCommand(T result, String groupname) { - super(HystrixCommandGroupKey.Factory.asKey(groupname)); - this.result = result; - } - - public FallbackCommand(T result, HystrixCommandGroupKey group) { - super(group); - this.result = result; - } - - public FallbackCommand(T result, HystrixCommandGroupKey group, int executionIsolationThreadTimeoutInMilliseconds) { - super(group, executionIsolationThreadTimeoutInMilliseconds); - this.result = result; - } - - public FallbackCommand(T result, HystrixCommandGroupKey group, HystrixThreadPoolKey threadPool) { - super(group, threadPool); - this.result = result; - } - - public FallbackCommand(T result, HystrixCommandGroupKey group, HystrixThreadPoolKey threadPool, int executionIsolationThreadTimeoutInMilliseconds) { - super(group, threadPool, executionIsolationThreadTimeoutInMilliseconds); - this.result = result; - } - - public FallbackCommand(T result, Setter setter) { - super(setter); - this.result = result; - } - - @Override - protected T run() throws Exception { - return this.result; - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/FeignHttpClientProperties.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/FeignHttpClientProperties.java deleted file mode 100644 index 501e3e7d5..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/FeignHttpClientProperties.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * - * * 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. - * - */ - -package org.springframework.cloud.netflix.feign.support; - -import java.util.concurrent.TimeUnit; -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * @author Ryan Baxter - */ -@ConfigurationProperties(prefix = "feign.httpclient") -public class FeignHttpClientProperties { - public static final boolean DEFAULT_DISABLE_SSL_VALIDATION = false; - public static final int DEFAULT_MAX_CONNECTIONS = 200; - public static final int DEFAULT_MAX_CONNECTIONS_PER_ROUTE = 50; - public static final long DEFAULT_TIME_TO_LIVE = 900L; - public static final TimeUnit DEFAULT_TIME_TO_LIVE_UNIT = TimeUnit.SECONDS; - public static final boolean DEFAULT_FOLLOW_REDIRECTS = true; - public static final int DEFAULT_CONNECTION_TIMEOUT = 2000; - public static final int DEFAULT_CONNECTION_TIMER_REPEAT = 3000; - - private boolean disableSslValidation = DEFAULT_DISABLE_SSL_VALIDATION; - private int maxConnections = DEFAULT_MAX_CONNECTIONS; - private int maxConnectionsPerRoute = DEFAULT_MAX_CONNECTIONS_PER_ROUTE; - private long timeToLive = DEFAULT_TIME_TO_LIVE; - private TimeUnit timeToLiveUnit = DEFAULT_TIME_TO_LIVE_UNIT; - private boolean followRedirects = DEFAULT_FOLLOW_REDIRECTS; - private int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT; - private int connectionTimerRepeat = DEFAULT_CONNECTION_TIMER_REPEAT; - - public int getConnectionTimerRepeat() { - return connectionTimerRepeat; - } - - public void setConnectionTimerRepeat(int connectionTimerRepeat) { - this.connectionTimerRepeat = connectionTimerRepeat; - } - - public boolean isDisableSslValidation() { - return disableSslValidation; - } - - public void setDisableSslValidation(boolean disableSslValidation) { - this.disableSslValidation = disableSslValidation; - } - - public int getMaxConnections() { - return maxConnections; - } - - public void setMaxConnections(int maxConnections) { - this.maxConnections = maxConnections; - } - - public int getMaxConnectionsPerRoute() { - return maxConnectionsPerRoute; - } - - public void setMaxConnectionsPerRoute(int maxConnectionsPerRoute) { - this.maxConnectionsPerRoute = maxConnectionsPerRoute; - } - - public long getTimeToLive() { - return timeToLive; - } - - public void setTimeToLive(long timeToLive) { - this.timeToLive = timeToLive; - } - - public TimeUnit getTimeToLiveUnit() { - return timeToLiveUnit; - } - - public void setTimeToLiveUnit(TimeUnit timeToLiveUnit) { - this.timeToLiveUnit = timeToLiveUnit; - } - - public boolean isFollowRedirects() { - return followRedirects; - } - - public void setFollowRedirects(boolean followRedirects) { - this.followRedirects = followRedirects; - } - - public int getConnectionTimeout() { - return connectionTimeout; - } - - public void setConnectionTimeout(int connectionTimeout) { - this.connectionTimeout = connectionTimeout; - } -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/FeignUtils.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/FeignUtils.java deleted file mode 100644 index bb0440fb9..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/FeignUtils.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.support; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.http.HttpHeaders; - -/** - * @author Spencer Gibb - */ -public class FeignUtils { - - static HttpHeaders getHttpHeaders(Map> headers) { - HttpHeaders httpHeaders = new HttpHeaders(); - for (Map.Entry> entry : headers.entrySet()) { - httpHeaders.put(entry.getKey(), new ArrayList<>(entry.getValue())); - } - return httpHeaders; - } - - static Map> getHeaders(HttpHeaders httpHeaders) { - LinkedHashMap> headers = new LinkedHashMap<>(); - - for (Map.Entry> entry : httpHeaders.entrySet()) { - headers.put(entry.getKey(), entry.getValue()); - } - - return headers; - } - -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/ResponseEntityDecoder.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/ResponseEntityDecoder.java deleted file mode 100644 index a9ccbc8c8..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/ResponseEntityDecoder.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.springframework.cloud.netflix.feign.support; - -import java.io.IOException; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.LinkedList; - -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; - -import feign.FeignException; -import feign.Response; -import feign.codec.Decoder; - -/** - * Decoder adds compatibility for Spring MVC's ResponseEntity to any other decoder via - * composition. - * @author chadjaros - */ -public class ResponseEntityDecoder implements Decoder { - - private Decoder decoder; - - public ResponseEntityDecoder(Decoder decoder) { - this.decoder = decoder; - } - - @Override - public Object decode(final Response response, Type type) throws IOException, - FeignException { - - if (isParameterizeHttpEntity(type)) { - type = ((ParameterizedType) type).getActualTypeArguments()[0]; - Object decodedObject = decoder.decode(response, type); - - return createResponse(decodedObject, response); - } - else if (isHttpEntity(type)) { - return createResponse(null, response); - } - else { - return decoder.decode(response, type); - } - } - - private boolean isParameterizeHttpEntity(Type type) { - if (type instanceof ParameterizedType) { - return isHttpEntity(((ParameterizedType) type).getRawType()); - } - return false; - } - - private boolean isHttpEntity(Type type) { - if (type instanceof Class) { - Class c = (Class) type; - return HttpEntity.class.isAssignableFrom(c); - } - return false; - } - - @SuppressWarnings("unchecked") - private ResponseEntity createResponse(Object instance, Response response) { - - MultiValueMap headers = new LinkedMultiValueMap<>(); - for (String key : response.headers().keySet()) { - headers.put(key, new LinkedList<>(response.headers().get(key))); - } - - return new ResponseEntity<>((T) instance, headers, HttpStatus.valueOf(response - .status())); - } -} \ No newline at end of file diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringDecoder.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringDecoder.java deleted file mode 100644 index 798ef5bd5..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringDecoder.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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.feign.support; - -import static org.springframework.cloud.netflix.feign.support.FeignUtils.getHttpHeaders; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.lang.reflect.WildcardType; - -import org.springframework.beans.factory.ObjectFactory; -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.client.HttpMessageConverterExtractor; - -import feign.FeignException; -import feign.Response; -import feign.codec.DecodeException; -import feign.codec.Decoder; - -/** - * @author Spencer Gibb - */ -public class SpringDecoder implements Decoder { - - private ObjectFactory messageConverters; - - public SpringDecoder(ObjectFactory messageConverters) { - this.messageConverters = messageConverters; - } - - @Override - public Object decode(final Response response, Type type) - throws IOException, FeignException { - if (type instanceof Class || type instanceof ParameterizedType - || type instanceof WildcardType) { - @SuppressWarnings({ "unchecked", "rawtypes" }) - HttpMessageConverterExtractor extractor = new HttpMessageConverterExtractor( - type, this.messageConverters.getObject().getConverters()); - - return extractor.extractData(new FeignResponseAdapter(response)); - } - throw new DecodeException( - "type is not an instance of Class or ParameterizedType: " + type); - } - - private class FeignResponseAdapter implements ClientHttpResponse { - - private final Response response; - - private FeignResponseAdapter(Response response) { - this.response = response; - } - - @Override - public HttpStatus getStatusCode() throws IOException { - return HttpStatus.valueOf(this.response.status()); - } - - @Override - public int getRawStatusCode() throws IOException { - return this.response.status(); - } - - @Override - public String getStatusText() throws IOException { - return this.response.reason(); - } - - @Override - public void close() { - try { - this.response.body().close(); - } - catch (IOException ex) { - // Ignore exception on close... - } - } - - @Override - public InputStream getBody() throws IOException { - return this.response.body().asInputStream(); - } - - @Override - public HttpHeaders getHeaders() { - return getHttpHeaders(this.response.headers()); - } - - } - -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringEncoder.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringEncoder.java deleted file mode 100644 index 83c187d13..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringEncoder.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * 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.feign.support; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.lang.reflect.Type; -import java.nio.charset.Charset; -import java.util.Collection; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.ObjectFactory; -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpOutputMessage; -import org.springframework.http.MediaType; -import org.springframework.http.converter.ByteArrayHttpMessageConverter; -import org.springframework.http.converter.HttpMessageConverter; - -import feign.RequestTemplate; -import feign.codec.EncodeException; -import feign.codec.Encoder; - -import static org.springframework.cloud.netflix.feign.support.FeignUtils.getHeaders; -import static org.springframework.cloud.netflix.feign.support.FeignUtils.getHttpHeaders; - -/** - * @author Spencer Gibb - */ -public class SpringEncoder implements Encoder { - - private static final Log log = LogFactory.getLog(SpringEncoder.class); - - private ObjectFactory messageConverters; - - public SpringEncoder(ObjectFactory messageConverters) { - this.messageConverters = messageConverters; - } - - @Override - public void encode(Object requestBody, Type bodyType, RequestTemplate request) - throws EncodeException { - // template.body(conversionService.convert(object, String.class)); - if (requestBody != null) { - Class requestType = requestBody.getClass(); - Collection contentTypes = request.headers().get("Content-Type"); - - MediaType requestContentType = null; - if (contentTypes != null && !contentTypes.isEmpty()) { - String type = contentTypes.iterator().next(); - requestContentType = MediaType.valueOf(type); - } - - for (HttpMessageConverter messageConverter : this.messageConverters - .getObject().getConverters()) { - if (messageConverter.canWrite(requestType, requestContentType)) { - if (log.isDebugEnabled()) { - if (requestContentType != null) { - log.debug("Writing [" + requestBody + "] as \"" - + requestContentType + "\" using [" - + messageConverter + "]"); - } - else { - log.debug("Writing [" + requestBody + "] using [" - + messageConverter + "]"); - } - - } - - FeignOutputMessage outputMessage = new FeignOutputMessage(request); - try { - @SuppressWarnings("unchecked") - HttpMessageConverter copy = (HttpMessageConverter) messageConverter; - copy.write(requestBody, requestContentType, outputMessage); - } - catch (IOException ex) { - throw new EncodeException("Error converting request body", ex); - } - // clear headers - request.headers(null); - // converters can modify headers, so update the request - // with the modified headers - request.headers(getHeaders(outputMessage.getHeaders())); - - // do not use charset for binary data - if (messageConverter instanceof ByteArrayHttpMessageConverter) { - request.body(outputMessage.getOutputStream().toByteArray(), null); - } else { - request.body(outputMessage.getOutputStream().toByteArray(), Charset.forName("UTF-8")); - } - return; - } - } - String message = "Could not write request: no suitable HttpMessageConverter " - + "found for request type [" + requestType.getName() + "]"; - if (requestContentType != null) { - message += " and content type [" + requestContentType + "]"; - } - throw new EncodeException(message); - } - } - - private class FeignOutputMessage implements HttpOutputMessage { - - private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - - private final HttpHeaders httpHeaders; - - private FeignOutputMessage(RequestTemplate request) { - httpHeaders = getHttpHeaders(request.headers()); - } - - @Override - public OutputStream getBody() throws IOException { - return this.outputStream; - } - - @Override - public HttpHeaders getHeaders() { - return this.httpHeaders; - } - - public ByteArrayOutputStream getOutputStream() { - return this.outputStream; - } - - } - -} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringMvcContract.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringMvcContract.java deleted file mode 100644 index 21eae7ac6..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringMvcContract.java +++ /dev/null @@ -1,378 +0,0 @@ -/* - * 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. - */ - -package org.springframework.cloud.netflix.feign.support; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.cloud.netflix.feign.AnnotatedParameterProcessor; -import org.springframework.cloud.netflix.feign.annotation.PathVariableParameterProcessor; -import org.springframework.cloud.netflix.feign.annotation.RequestHeaderParameterProcessor; -import org.springframework.cloud.netflix.feign.annotation.RequestParamParameterProcessor; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.ResourceLoaderAware; -import org.springframework.core.DefaultParameterNameDiscoverer; -import org.springframework.core.ParameterNameDiscoverer; -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.core.convert.ConversionService; -import org.springframework.core.convert.support.DefaultConversionService; -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.ResourceLoader; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import static feign.Util.checkState; -import static feign.Util.emptyToNull; -import static org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation; - -import feign.Contract; -import feign.Feign; -import feign.MethodMetadata; -import feign.Param; - -/** - * @author Spencer Gibb - * @author Abhijit Sarkar - */ -public class SpringMvcContract extends Contract.BaseContract - implements ResourceLoaderAware { - - private static final String ACCEPT = "Accept"; - - private static final String CONTENT_TYPE = "Content-Type"; - - private static final ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer(); - - private final Map, AnnotatedParameterProcessor> annotatedArgumentProcessors; - private final Map processedMethods = new HashMap<>(); - - private final ConversionService conversionService; - private final Param.Expander expander; - private ResourceLoader resourceLoader = new DefaultResourceLoader(); - - public SpringMvcContract() { - this(Collections.emptyList()); - } - - public SpringMvcContract( - List annotatedParameterProcessors) { - this(annotatedParameterProcessors, new DefaultConversionService()); - } - - public SpringMvcContract( - List annotatedParameterProcessors, - ConversionService conversionService) { - Assert.notNull(annotatedParameterProcessors, - "Parameter processors can not be null."); - Assert.notNull(conversionService, "ConversionService can not be null."); - - List processors; - if (!annotatedParameterProcessors.isEmpty()) { - processors = new ArrayList<>(annotatedParameterProcessors); - } - else { - processors = getDefaultAnnotatedArgumentsProcessors(); - } - this.annotatedArgumentProcessors = toAnnotatedArgumentProcessorMap(processors); - this.conversionService = conversionService; - this.expander = new ConvertingExpander(conversionService); - } - - @Override - public void setResourceLoader(ResourceLoader resourceLoader) { - this.resourceLoader = resourceLoader; - } - - @Override - protected void processAnnotationOnClass(MethodMetadata data, Class clz) { - if (clz.getInterfaces().length == 0) { - RequestMapping classAnnotation = findMergedAnnotation(clz, - RequestMapping.class); - if (classAnnotation != null) { - // Prepend path from class annotation if specified - if (classAnnotation.value().length > 0) { - String pathValue = emptyToNull(classAnnotation.value()[0]); - pathValue = resolve(pathValue); - if (!pathValue.startsWith("/")) { - pathValue = "/" + pathValue; - } - data.template().insert(0, pathValue); - } - } - } - } - - @Override - public MethodMetadata parseAndValidateMetadata(Class targetType, Method method) { - this.processedMethods.put(Feign.configKey(targetType, method), method); - MethodMetadata md = super.parseAndValidateMetadata(targetType, method); - - RequestMapping classAnnotation = findMergedAnnotation(targetType, - RequestMapping.class); - if (classAnnotation != null) { - // produces - use from class annotation only if method has not specified this - if (!md.template().headers().containsKey(ACCEPT)) { - parseProduces(md, method, classAnnotation); - } - - // consumes -- use from class annotation only if method has not specified this - if (!md.template().headers().containsKey(CONTENT_TYPE)) { - parseConsumes(md, method, classAnnotation); - } - - // headers -- class annotation is inherited to methods, always write these if - // present - parseHeaders(md, method, classAnnotation); - } - return md; - } - - @Override - protected void processAnnotationOnMethod(MethodMetadata data, - Annotation methodAnnotation, Method method) { - if (!RequestMapping.class.isInstance(methodAnnotation) && !methodAnnotation - .annotationType().isAnnotationPresent(RequestMapping.class)) { - return; - } - - RequestMapping methodMapping = findMergedAnnotation(method, RequestMapping.class); - // HTTP Method - RequestMethod[] methods = methodMapping.method(); - if (methods.length == 0) { - methods = new RequestMethod[] { RequestMethod.GET }; - } - checkOne(method, methods, "method"); - data.template().method(methods[0].name()); - - // path - checkAtMostOne(method, methodMapping.value(), "value"); - if (methodMapping.value().length > 0) { - String pathValue = emptyToNull(methodMapping.value()[0]); - if (pathValue != null) { - pathValue = resolve(pathValue); - // Append path from @RequestMapping if value is present on method - if (!pathValue.startsWith("/") - && !data.template().toString().endsWith("/")) { - pathValue = "/" + pathValue; - } - data.template().append(pathValue); - } - } - - // produces - parseProduces(data, method, methodMapping); - - // consumes - parseConsumes(data, method, methodMapping); - - // headers - parseHeaders(data, method, methodMapping); - - data.indexToExpander(new LinkedHashMap()); - } - - private String resolve(String value) { - if (StringUtils.hasText(value) - && this.resourceLoader instanceof ConfigurableApplicationContext) { - return ((ConfigurableApplicationContext) this.resourceLoader).getEnvironment() - .resolvePlaceholders(value); - } - return value; - } - - private void checkAtMostOne(Method method, Object[] values, String fieldName) { - checkState(values != null && (values.length == 0 || values.length == 1), - "Method %s can only contain at most 1 %s field. Found: %s", - method.getName(), fieldName, - values == null ? null : Arrays.asList(values)); - } - - private void checkOne(Method method, Object[] values, String fieldName) { - checkState(values != null && values.length == 1, - "Method %s can only contain 1 %s field. Found: %s", method.getName(), - fieldName, values == null ? null : Arrays.asList(values)); - } - - @Override - protected boolean processAnnotationsOnParameter(MethodMetadata data, - Annotation[] annotations, int paramIndex) { - boolean isHttpAnnotation = false; - - AnnotatedParameterProcessor.AnnotatedParameterContext context = new SimpleAnnotatedParameterContext( - data, paramIndex); - Method method = this.processedMethods.get(data.configKey()); - for (Annotation parameterAnnotation : annotations) { - AnnotatedParameterProcessor processor = this.annotatedArgumentProcessors - .get(parameterAnnotation.annotationType()); - if (processor != null) { - Annotation processParameterAnnotation; - // synthesize, handling @AliasFor, while falling back to parameter name on - // missing String #value(): - processParameterAnnotation = synthesizeWithMethodParameterNameAsFallbackValue( - parameterAnnotation, method, paramIndex); - isHttpAnnotation |= processor.processArgument(context, - processParameterAnnotation, method); - } - } - if (isHttpAnnotation && data.indexToExpander().get(paramIndex) == null - && this.conversionService.canConvert( - method.getParameterTypes()[paramIndex], String.class)) { - data.indexToExpander().put(paramIndex, this.expander); - } - return isHttpAnnotation; - } - - private void parseProduces(MethodMetadata md, Method method, - RequestMapping annotation) { - String[] serverProduces = annotation.produces(); - String clientAccepts = serverProduces.length == 0 ? null - : emptyToNull(serverProduces[0]); - if (clientAccepts != null) { - md.template().header(ACCEPT, clientAccepts); - } - } - - private void parseConsumes(MethodMetadata md, Method method, - RequestMapping annotation) { - String[] serverConsumes = annotation.consumes(); - String clientProduces = serverConsumes.length == 0 ? null - : emptyToNull(serverConsumes[0]); - if (clientProduces != null) { - md.template().header(CONTENT_TYPE, clientProduces); - } - } - - private void parseHeaders(MethodMetadata md, Method method, - RequestMapping annotation) { - // TODO: only supports one header value per key - if (annotation.headers() != null && annotation.headers().length > 0) { - for (String header : annotation.headers()) { - int index = header.indexOf('='); - if (!header.contains("!=") && index >= 0) { - md.template().header(resolve(header.substring(0, index)), - resolve(header.substring(index + 1).trim())); - } - } - } - } - - private Map, AnnotatedParameterProcessor> toAnnotatedArgumentProcessorMap( - List processors) { - Map, AnnotatedParameterProcessor> result = new HashMap<>(); - for (AnnotatedParameterProcessor processor : processors) { - result.put(processor.getAnnotationType(), processor); - } - return result; - } - - private List getDefaultAnnotatedArgumentsProcessors() { - - List annotatedArgumentResolvers = new ArrayList<>(); - - annotatedArgumentResolvers.add(new PathVariableParameterProcessor()); - annotatedArgumentResolvers.add(new RequestParamParameterProcessor()); - annotatedArgumentResolvers.add(new RequestHeaderParameterProcessor()); - - return annotatedArgumentResolvers; - } - - private Annotation synthesizeWithMethodParameterNameAsFallbackValue( - Annotation parameterAnnotation, Method method, int parameterIndex) { - Map annotationAttributes = AnnotationUtils - .getAnnotationAttributes(parameterAnnotation); - Object defaultValue = AnnotationUtils.getDefaultValue(parameterAnnotation); - if (defaultValue instanceof String - && defaultValue.equals(annotationAttributes.get(AnnotationUtils.VALUE))) { - Type[] parameterTypes = method.getGenericParameterTypes(); - String[] parameterNames = PARAMETER_NAME_DISCOVERER.getParameterNames(method); - if (shouldAddParameterName(parameterIndex, parameterTypes, parameterNames)) { - annotationAttributes.put(AnnotationUtils.VALUE, - parameterNames[parameterIndex]); - } - } - return AnnotationUtils.synthesizeAnnotation(annotationAttributes, - parameterAnnotation.annotationType(), null); - } - - private boolean shouldAddParameterName(int parameterIndex, Type[] parameterTypes, String[] parameterNames) { - // has a parameter name - return parameterNames != null && parameterNames.length > parameterIndex - // has a type - && parameterTypes != null && parameterTypes.length > parameterIndex; - } - - private class SimpleAnnotatedParameterContext - implements AnnotatedParameterProcessor.AnnotatedParameterContext { - - private final MethodMetadata methodMetadata; - - private final int parameterIndex; - - public SimpleAnnotatedParameterContext(MethodMetadata methodMetadata, - int parameterIndex) { - this.methodMetadata = methodMetadata; - this.parameterIndex = parameterIndex; - } - - @Override - public MethodMetadata getMethodMetadata() { - return this.methodMetadata; - } - - @Override - public int getParameterIndex() { - return this.parameterIndex; - } - - @Override - public void setParameterName(String name) { - nameParam(this.methodMetadata, name, this.parameterIndex); - } - - @Override - public Collection setTemplateParameter(String name, - Collection rest) { - return addTemplatedParam(rest, name); - } - } - - public static class ConvertingExpander implements Param.Expander { - - private final ConversionService conversionService; - - public ConvertingExpander(ConversionService conversionService) { - this.conversionService = conversionService; - } - - @Override - public String expand(Object value) { - return this.conversionService.convert(value, String.class); - } - - } -} diff --git a/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories index d14e89022..b880d3d93 100644 --- a/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories @@ -1,8 +1,4 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientAutoConfiguration,\ -org.springframework.cloud.netflix.feign.FeignAutoConfiguration,\ -org.springframework.cloud.netflix.feign.encoding.FeignAcceptGzipEncodingAutoConfiguration,\ -org.springframework.cloud.netflix.feign.encoding.FeignContentGzipEncodingAutoConfiguration,\ org.springframework.cloud.netflix.hystrix.HystrixAutoConfiguration,\ org.springframework.cloud.netflix.hystrix.security.HystrixSecurityAutoConfiguration,\ org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/EnableFeignClientsTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/EnableFeignClientsTests.java deleted file mode 100644 index 73c24b381..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/EnableFeignClientsTests.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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.feign; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.feign.support.SpringEncoder; -import org.springframework.cloud.netflix.feign.support.SpringMvcContract; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import feign.Contract; -import feign.Feign; -import feign.Logger; -import feign.codec.Decoder; -import feign.codec.Encoder; -import feign.optionals.OptionalDecoder; -import feign.slf4j.Slf4jLogger; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = EnableFeignClientsTests.PlainConfiguration.class) -@DirtiesContext -public class EnableFeignClientsTests { - - @Autowired - private FeignContext feignContext; - - @Test - public void decoderDefaultCorrect() { - OptionalDecoder.class - .cast(this.feignContext.getInstance("foo", Decoder.class)); - } - - @Test - public void encoderDefaultCorrect() { - SpringEncoder.class.cast(this.feignContext.getInstance("foo", Encoder.class)); - } - - @Test - public void loggerDefaultCorrect() { - Slf4jLogger.class.cast(this.feignContext.getInstance("foo", Logger.class)); - } - - @Test - public void contractDefaultCorrect() { - SpringMvcContract.class - .cast(this.feignContext.getInstance("foo", Contract.class)); - } - - @Test - public void builderDefaultCorrect() { - Feign.Builder.class - .cast(this.feignContext.getInstance("foo", Feign.Builder.class)); - } - - @Configuration - @Import({ PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class, - FeignAutoConfiguration.class }) - protected static class PlainConfiguration { - } - -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientFactoryTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientFactoryTests.java deleted file mode 100644 index e3587367a..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientFactoryTests.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2013-2015 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.feign; - -import org.junit.Test; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; - -import java.util.Arrays; - -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertThat; - -/** - * @author Spencer Gibb - */ -public class FeignClientFactoryTests { - - @Test - public void testChildContexts() { - AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(); - parent.refresh(); - FeignContext context = new FeignContext(); - context.setApplicationContext(parent); - context.setConfigurations(Arrays.asList(getSpec("foo", FooConfig.class), - getSpec("bar", BarConfig.class))); - - Foo foo = context.getInstance("foo", Foo.class); - assertThat("foo was null", foo, is(notNullValue())); - - Bar bar = context.getInstance("bar", Bar.class); - assertThat("bar was null", bar, is(notNullValue())); - - Bar foobar = context.getInstance("foo", Bar.class); - assertThat("bar was not null", foobar, is(nullValue())); - } - - private FeignClientSpecification getSpec(String name, Class configClass) { - return new FeignClientSpecification(name, new Class[]{configClass}); - } - - static class FooConfig { - @Bean - Foo foo() { - return new Foo(); - } - - } - static class Foo{} - - static class BarConfig { - @Bean - Bar bar() { - return new Bar(); - } - } - static class Bar{} -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientOverrideDefaultsTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientOverrideDefaultsTests.java deleted file mode 100644 index bf07fdddb..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientOverrideDefaultsTests.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * 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.feign; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.feign.support.SpringEncoder; -import org.springframework.cloud.netflix.feign.support.SpringMvcContract; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -import feign.Contract; -import feign.Feign; -import feign.Logger; -import feign.Request; -import feign.RequestInterceptor; -import feign.RequestLine; -import feign.RequestTemplate; -import feign.Retryer; -import feign.auth.BasicAuthRequestInterceptor; -import feign.codec.Decoder; -import feign.codec.Encoder; -import feign.codec.ErrorDecoder; -import feign.hystrix.HystrixFeign; -import feign.optionals.OptionalDecoder; -import feign.slf4j.Slf4jLogger; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = FeignClientOverrideDefaultsTests.TestConfiguration.class) -@DirtiesContext -public class FeignClientOverrideDefaultsTests { - - @Autowired - private FeignContext context; - - @Autowired - private FooClient foo; - - @Autowired - private BarClient bar; - - @Test - public void clientsAvailable() { - assertNotNull(this.foo); - assertNotNull(this.bar); - } - - @Test - public void overrideDecoder() { - Decoder.Default.class.cast(this.context.getInstance("foo", Decoder.class)); - OptionalDecoder.class.cast(this.context.getInstance("bar", Decoder.class)); - } - - @Test - public void overrideEncoder() { - Encoder.Default.class.cast(this.context.getInstance("foo", Encoder.class)); - SpringEncoder.class.cast(this.context.getInstance("bar", Encoder.class)); - } - - @Test - public void overrideLogger() { - Logger.JavaLogger.class.cast(this.context.getInstance("foo", Logger.class)); - Slf4jLogger.class.cast(this.context.getInstance("bar", Logger.class)); - } - - @Test - public void overrideContract() { - Contract.Default.class.cast(this.context.getInstance("foo", Contract.class)); - SpringMvcContract.class.cast(this.context.getInstance("bar", Contract.class)); - } - - @Test - public void overrideLoggerLevel() { - assertNull(this.context.getInstance("foo", Logger.Level.class)); - assertEquals(Logger.Level.HEADERS, - this.context.getInstance("bar", Logger.Level.class)); - } - - @Test - public void overrideRetryer() { - assertEquals(Retryer.NEVER_RETRY, this.context.getInstance("foo", Retryer.class)); - Retryer.Default.class.cast(this.context.getInstance("bar", Retryer.class)); - } - - @Test - public void overrideErrorDecoder() { - assertNull(this.context.getInstance("foo", ErrorDecoder.class)); - ErrorDecoder.Default.class - .cast(this.context.getInstance("bar", ErrorDecoder.class)); - } - - @Test - public void overrideBuilder() { - HystrixFeign.Builder.class.cast(this.context.getInstance("foo", Feign.Builder.class)); - Feign.Builder.class - .cast(this.context.getInstance("bar", Feign.Builder.class)); - } - - @Test - public void overrideRequestOptions() { - assertNull(this.context.getInstance("foo", Request.Options.class)); - Request.Options options = this.context.getInstance("bar", Request.Options.class); - assertEquals(1, options.connectTimeoutMillis()); - assertEquals(1, options.readTimeoutMillis()); - } - - @Test - public void addRequestInterceptor() { - assertEquals(1, - this.context.getInstances("foo", RequestInterceptor.class).size()); - assertEquals(2, - this.context.getInstances("bar", RequestInterceptor.class).size()); - } - - @Configuration - @EnableFeignClients(clients = { FooClient.class, BarClient.class }) - @Import({ PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class, - FeignAutoConfiguration.class }) - protected static class TestConfiguration { - @Bean - RequestInterceptor defaultRequestInterceptor() { - return new RequestInterceptor() { - @Override - public void apply(RequestTemplate template) { - } - }; - } - } - - @FeignClient(name = "foo", url = "http://foo", configuration = FooConfiguration.class) - interface FooClient { - @RequestLine("GET /") - String get(); - - } - - public static class FooConfiguration { - @Bean - public Decoder feignDecoder() { - return new Decoder.Default(); - } - - @Bean - public Encoder feignEncoder() { - return new Encoder.Default(); - } - - @Bean - public Logger feignLogger() { - return new Logger.JavaLogger(); - } - - @Bean - public Contract feignContract() { - return new Contract.Default(); - } - - @Bean - public Feign.Builder feignBuilder() { - return HystrixFeign.builder(); - } - } - - @FeignClient(name = "bar", url = "http://bar", configuration = BarConfiguration.class) - interface BarClient { - @RequestMapping(value = "/", method = RequestMethod.GET) - String get(); - } - - public static class BarConfiguration { - @Bean - Logger.Level feignLevel() { - return Logger.Level.HEADERS; - } - - @Bean - Retryer feignRetryer() { - return new Retryer.Default(); - } - - @Bean - ErrorDecoder feignErrorDecoder() { - return new ErrorDecoder.Default(); - } - - @Bean - Request.Options feignRequestOptions() { - return new Request.Options(1, 1); - } - - @Bean - RequestInterceptor feignRequestInterceptor() { - return new BasicAuthRequestInterceptor("user", "pass"); - } - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientUsingPropertiesTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientUsingPropertiesTests.java deleted file mode 100644 index c56c62079..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientUsingPropertiesTests.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright 2013-2018 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.feign; - -import feign.RequestInterceptor; -import feign.RequestTemplate; -import feign.RetryableException; -import feign.Retryer; -import feign.codec.EncodeException; -import feign.codec.Encoder; -import feign.codec.ErrorDecoder; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpServletRequest; -import java.lang.reflect.Type; -import java.util.Collections; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -/** - * @author Eko Kurniawan Khannedy - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = FeignClientUsingPropertiesTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT) -@TestPropertySource("classpath:feign-properties.properties") -@DirtiesContext -public class FeignClientUsingPropertiesTests { - - @Autowired - FeignContext context; - - @Autowired - private ApplicationContext applicationContext; - - @Value("${local.server.port}") - private int port = 0; - - private FeignClientFactoryBean fooFactoryBean; - - private FeignClientFactoryBean barFactoryBean; - - private FeignClientFactoryBean formFactoryBean; - - public FeignClientUsingPropertiesTests() { - fooFactoryBean = new FeignClientFactoryBean(); - fooFactoryBean.setName("foo"); - fooFactoryBean.setType(FeignClientFactoryBean.class); - - barFactoryBean = new FeignClientFactoryBean(); - barFactoryBean.setName("bar"); - barFactoryBean.setType(FeignClientFactoryBean.class); - - formFactoryBean = new FeignClientFactoryBean(); - formFactoryBean.setName("form"); - formFactoryBean.setType(FeignClientFactoryBean.class); - } - - public FooClient fooClient() { - fooFactoryBean.setApplicationContext(applicationContext); - return fooFactoryBean.feign(context).target(FooClient.class, "http://localhost:" + this.port); - } - - public BarClient barClient() { - barFactoryBean.setApplicationContext(applicationContext); - return barFactoryBean.feign(context).target(BarClient.class, "http://localhost:" + this.port); - } - - public FormClient formClient() { - formFactoryBean.setApplicationContext(applicationContext); - return formFactoryBean.feign(context).target(FormClient.class, "http://localhost:" + this.port); - } - - @Test - public void testFoo() { - String response = fooClient().foo(); - assertEquals("OK", response); - } - - @Test(expected = RetryableException.class) - public void testBar() { - barClient().bar(); - fail("it should timeout"); - } - - @Test - public void testForm() { - Map request = Collections.singletonMap("form", "Data"); - String response = formClient().form(request); - assertEquals("Data", response); - } - - protected interface FooClient { - - @RequestMapping(method = RequestMethod.GET, value = "/foo") - String foo(); - } - - protected interface BarClient { - - @RequestMapping(method = RequestMethod.GET, value = "/bar") - String bar(); - } - - protected interface FormClient { - - @RequestMapping(value = "/form", method = RequestMethod.POST, - consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) - String form(Map form); - - } - - @Configuration - @EnableAutoConfiguration - @RestController - protected static class Application { - - @RequestMapping(method = RequestMethod.GET, value = "/foo") - public String foo(HttpServletRequest request) throws IllegalAccessException { - if ("Foo".equals(request.getHeader("Foo")) && - "Bar".equals(request.getHeader("Bar"))) { - return "OK"; - } else { - throw new IllegalAccessException("It should has Foo and Bar header"); - } - } - - @RequestMapping(method = RequestMethod.GET, value = "/bar") - public String bar() throws InterruptedException { - Thread.sleep(2000L); - return "OK"; - } - - @RequestMapping(value = "/form", method = RequestMethod.POST, - consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) - public String form(HttpServletRequest request) { - return request.getParameter("form"); - } - - } - - public static class FooRequestInterceptor implements RequestInterceptor { - @Override - public void apply(RequestTemplate template) { - template.header("Foo", "Foo"); - } - } - - public static class BarRequestInterceptor implements RequestInterceptor { - @Override - public void apply(RequestTemplate template) { - template.header("Bar", "Bar"); - } - } - - public static class NoRetryer implements Retryer { - - @Override - public void continueOrPropagate(RetryableException e) { - throw e; - } - - @Override - public Retryer clone() { - return this; - } - } - - public static class DefaultErrorDecoder extends ErrorDecoder.Default { - } - - public static class FormEncoder implements Encoder { - - @Override - public void encode(Object o, Type type, RequestTemplate requestTemplate) throws EncodeException { - Map form = (Map) o; - StringBuilder builder = new StringBuilder(); - form.forEach((key, value) -> { - builder.append(key + "=" + value + "&"); - }); - - requestTemplate.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE); - requestTemplate.body(builder.toString()); - } - } - -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrarTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrarTests.java deleted file mode 100644 index e82804492..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrarTests.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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. - * - */ - -package org.springframework.cloud.netflix.feign; - -import java.util.Collections; - -import org.junit.Test; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.mock.env.MockEnvironment; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -/** - * @author Spencer Gibb - * @author Gang Li - */ -public class FeignClientsRegistrarTests { - - @Test(expected = IllegalStateException.class) - public void badNameHttpPrefix() { - testGetName("http://bad_hostname"); - } - - - @Test(expected = IllegalStateException.class) - public void badNameHttpsPrefix() { - testGetName("https://bad_hostname"); - } - - @Test(expected = IllegalStateException.class) - public void badName() { - testGetName("bad_hostname"); - } - - @Test(expected = IllegalStateException.class) - public void badNameStartsWithHttp() { - testGetName("http_bad_hostname"); - } - - @Test - public void goodName() { - String name = testGetName("good-name"); - assertThat("name was wrong", name, is("good-name")); - } - - @Test - public void goodNameHttpPrefix() { - String name = testGetName("http://good-name"); - assertThat("name was wrong", name, is("http://good-name")); - } - - @Test - public void goodNameHttpsPrefix() { - String name = testGetName("https://goodname"); - assertThat("name was wrong", name, is("https://goodname")); - } - - private String testGetName(String name) { - FeignClientsRegistrar registrar = new FeignClientsRegistrar(); - registrar.setEnvironment(new MockEnvironment()); - return registrar.getName(Collections.singletonMap("name", name)); - } - - - @Test(expected = IllegalArgumentException.class) - public void testFallback() { - new AnnotationConfigApplicationContext(FallbackTestConfig.class); - } - - @Test(expected = IllegalArgumentException.class) - public void testFallbackFactory() { - new AnnotationConfigApplicationContext(FallbackFactoryTestConfig.class); - } - - @Configuration - @EnableAutoConfiguration - @EnableFeignClients(clients = { FeignClientsRegistrarTests.FallbackClient.class}) - protected static class FallbackTestConfig { - - } - - @FeignClient(name = "fallbackTestClient", url = "http://localhost:8080/", fallback = FallbackClient.class) - protected interface FallbackClient { - @RequestMapping(method = RequestMethod.GET, value = "/hello") - String fallbackTest(); - } - - @Configuration - @EnableAutoConfiguration - @EnableFeignClients(clients = { FeignClientsRegistrarTests.FallbackFactoryClient.class}) - protected static class FallbackFactoryTestConfig { - - } - - @FeignClient(name = "fallbackFactoryTestClient", url = "http://localhost:8081/", fallbackFactory = FallbackFactoryClient.class) - protected interface FallbackFactoryClient { - @RequestMapping(method = RequestMethod.GET, value = "/hello") - String fallbackFactoryTest(); - } - -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignCompressionTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignCompressionTests.java deleted file mode 100644 index 2a636fb2d..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignCompressionTests.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2013-2018 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.feign; - -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.feign.encoding.FeignAcceptGzipEncodingAutoConfiguration; -import org.springframework.cloud.netflix.feign.encoding.FeignAcceptGzipEncodingInterceptor; -import org.springframework.cloud.netflix.feign.encoding.FeignContentGzipEncodingAutoConfiguration; -import org.springframework.cloud.netflix.feign.encoding.FeignContentGzipEncodingInterceptor; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.cloud.test.ModifiedClassPathRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import feign.Client; -import feign.RequestInterceptor; -import feign.httpclient.ApacheHttpClient; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - * @author Biju Kunjummen - */ -@RunWith(ModifiedClassPathRunner.class) -@ClassPathExclusions({ "ribbon-loadbalancer-{version:\\d.*}.jar" }) -public class FeignCompressionTests { - - @Test - public void testInterceptors() { - new ApplicationContextRunner() - .withPropertyValues("feign.compression.response.enabled=true", - "feign.compression.request.enabled=true", - "feign.okhttp.enabled=false") - .withConfiguration(AutoConfigurations.of(ArchaiusAutoConfiguration.class, - FeignAutoConfiguration.class, - FeignContentGzipEncodingAutoConfiguration.class, - FeignAcceptGzipEncodingAutoConfiguration.class, - HttpClientConfiguration.class, PlainConfig.class)) - .run(context -> { - FeignContext feignContext = context.getBean(FeignContext.class); - Map interceptors = feignContext - .getInstances("foo", RequestInterceptor.class); - assertThat(interceptors.size()).isEqualTo(2); - assertThat(interceptors.get("feignAcceptGzipEncodingInterceptor")) - .isInstanceOf(FeignAcceptGzipEncodingInterceptor.class); - assertThat(interceptors.get("feignContentGzipEncodingInterceptor")) - .isInstanceOf(FeignContentGzipEncodingInterceptor.class); - }); - } - - @Configuration - protected static class PlainConfig { - - @Autowired - private Client client; - - @Bean - public ApacheHttpClient client() { - /* - * We know our client is an AppacheHttpClient because we disabled the OK HTTP - * client. FeignAcceptGzipEncodingAutoConfiguration won't load unless there is - * a bean of type ApacheHttpClient (not Client) in this test because the bean - * is not yet created and so the application context doesnt know that the - * Client bean is actually an instance of ApacheHttpClient, therefore - * FeignAcceptGzipEncodingAutoConfiguration will not be loaded. We just create - * a bean here of type ApacheHttpClient so that the configuration will be - * loaded correctly. - */ - return (ApacheHttpClient) client; - } - } -} \ No newline at end of file diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignHttpClientConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignHttpClientConfigurationTests.java deleted file mode 100644 index 43f388a89..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignHttpClientConfigurationTests.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2013-2018 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.feign; - -import java.lang.reflect.Field; -import javax.net.ssl.SSLContextSpi; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.X509TrustManager; -import org.apache.http.config.Lookup; -import org.apache.http.conn.HttpClientConnectionManager; -import org.apache.http.conn.socket.ConnectionSocketFactory; -import org.apache.http.impl.conn.DefaultHttpClientConnectionOperator; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.cloud.test.ModifiedClassPathRunner; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.util.ReflectionUtils; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -/** - * @author Ryan Baxter - */ -@RunWith(ModifiedClassPathRunner.class) -@ClassPathExclusions({ "ribbon-loadbalancer-{version:\\d.*}.jar" }) -public class FeignHttpClientConfigurationTests { - - private ConfigurableApplicationContext context; - - @Before - public void setUp() { - context = new SpringApplicationBuilder().properties("debug=true","feign.httpclient.disableSslValidation=true").web(false) - .sources(HttpClientConfiguration.class, FeignAutoConfiguration.class).run(); - } - - @After - public void tearDown() { - if(context != null) { - context.close(); - } - } - - @Test - public void disableSslTest() throws Exception { - HttpClientConnectionManager connectionManager = context.getBean(HttpClientConnectionManager.class); - Lookup socketFactoryRegistry = getConnectionSocketFactoryLookup(connectionManager); - assertNotNull(socketFactoryRegistry.lookup("https")); - assertNull(this.getX509TrustManager(socketFactoryRegistry).getAcceptedIssuers()); - } - - private Lookup getConnectionSocketFactoryLookup(HttpClientConnectionManager connectionManager) { - DefaultHttpClientConnectionOperator connectionOperator = (DefaultHttpClientConnectionOperator)this.getField(connectionManager, "connectionOperator"); - return (Lookup)this.getField(connectionOperator, "socketFactoryRegistry"); - } - - private X509TrustManager getX509TrustManager(Lookup socketFactoryRegistry) { - ConnectionSocketFactory connectionSocketFactory = (ConnectionSocketFactory)socketFactoryRegistry.lookup("https"); - SSLSocketFactory sslSocketFactory = (SSLSocketFactory)this.getField(connectionSocketFactory, "socketfactory"); - SSLContextSpi sslContext = (SSLContextSpi)this.getField(sslSocketFactory, "context"); - return (X509TrustManager)this.getField(sslContext, "trustManager"); - } - - protected Object getField(Object target, String name) { - Field field = ReflectionUtils.findField(target.getClass(), name); - ReflectionUtils.makeAccessible(field); - Object value = ReflectionUtils.getField(field, target); - return value; - } - -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignHttpClientUrlTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignHttpClientUrlTests.java deleted file mode 100644 index 38fcd89f8..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignHttpClientUrlTests.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * 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. - * - */ - -package org.springframework.cloud.netflix.feign; - -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; - -import java.lang.reflect.Field; -import java.util.Objects; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.SocketUtils; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import feign.Client; -import feign.Feign; -import feign.Target; -import feign.httpclient.ApacheHttpClient; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = FeignHttpClientUrlTests.TestConfig.class, webEnvironment = WebEnvironment.DEFINED_PORT, value = { - "spring.application.name=feignclienturltest", "feign.hystrix.enabled=false", - "feign.okhttp.enabled=false" }) -@DirtiesContext -public class FeignHttpClientUrlTests { - - static int port; - - @BeforeClass - public static void beforeClass() { - port = SocketUtils.findAvailableTcpPort(); - System.setProperty("server.port", String.valueOf(port)); - } - - @AfterClass - public static void afterClass() { - System.clearProperty("server.port"); - } - - @Autowired - private UrlClient urlClient; - - @Autowired - private BeanUrlClient beanClient; - - @Autowired BeanUrlClientNoProtocol beanClientNoProtocol; - - // this tests that - @FeignClient(name = "localappurl", url = "http://localhost:${server.port}/") - protected interface UrlClient { - @RequestMapping(method = RequestMethod.GET, value = "/hello") - Hello getHello(); - } - - @FeignClient(name = "beanappurl", url = "#{SERVER_URL}path") - protected interface BeanUrlClient { - @RequestMapping(method = RequestMethod.GET, value = "/hello") - Hello getHello(); - } - - @FeignClient(name = "beanappurlnoprotocol", url = "#{SERVER_URL_NO_PROTOCOL}path") - protected interface BeanUrlClientNoProtocol { - @RequestMapping(method = RequestMethod.GET, value = "/hello") - Hello getHello(); - } - - @Configuration - @EnableAutoConfiguration - @RestController - @EnableFeignClients(clients = { UrlClient.class, BeanUrlClient.class, BeanUrlClientNoProtocol.class }) - protected static class TestConfig { - - @RequestMapping(method = RequestMethod.GET, value = "/hello") - public Hello getHello() { - return new Hello("hello world 1"); - } - - @RequestMapping(method = RequestMethod.GET, value = "/path/hello") - public Hello getHelloWithPath() { - return getHello(); - } - - @Bean(name="SERVER_URL") - public String serverUrl() { - return "http://localhost:" + port + "/"; - } - - @Bean(name="SERVER_URL_NO_PROTOCOL") - public String serverUrlNoProtocol() { - return "localhost:" + port + "/"; - } - - @Bean - public Targeter feignTargeter() { - return new Targeter() { - @Override - public T target(FeignClientFactoryBean factory, Feign.Builder feign, - FeignContext context, Target.HardCodedTarget target) { - Field field = ReflectionUtils.findField(Feign.Builder.class, - "client"); - ReflectionUtils.makeAccessible(field); - Client client = (Client) ReflectionUtils.getField(field, feign); - if (target.name().equals("localappurl")) { - assertThat("client was wrong type", client, - is(instanceOf(ApacheHttpClient.class))); - } - return feign.target(target); - } - }; - } - - } - - @Test - public void testUrlHttpClient() { - assertNotNull("UrlClient was null", this.urlClient); - Hello hello = this.urlClient.getHello(); - assertNotNull("hello was null", hello); - assertEquals("first hello didn't match", new Hello("hello world 1"), hello); - } - - @Test - public void testBeanUrl() { - Hello hello = this.beanClient.getHello(); - assertNotNull("hello was null", hello); - assertEquals("first hello didn't match", new Hello("hello world 1"), hello); - } - - @Test - public void testBeanUrlNoProtocol() { - Hello hello = this.beanClientNoProtocol.getHello(); - assertNotNull("hello was null", hello); - assertEquals("first hello didn't match", new Hello("hello world 1"), hello); - } - - public static class Hello { - private String message; - - public Hello() { - } - - public Hello(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Hello that = (Hello) o; - return Objects.equals(message, that.message); - } - - @Override - public int hashCode() { - return Objects.hash(message); - } - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignLoggerFactoryTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignLoggerFactoryTests.java deleted file mode 100644 index c773ab4d8..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignLoggerFactoryTests.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 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. - */ - -package org.springframework.cloud.netflix.feign; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -import feign.Logger; -import feign.slf4j.Slf4jLogger; - -/** - * @author Venil Noronha - */ -public class FeignLoggerFactoryTests { - - @Test - public void testDefaultLogger() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleConfiguration1.class); - FeignLoggerFactory loggerFactory = context.getBean(FeignLoggerFactory.class); - assertNotNull(loggerFactory); - Logger logger = loggerFactory.create(Object.class); - assertNotNull(logger); - assertTrue(logger instanceof Slf4jLogger); - context.close(); - } - - @Configuration - @Import(FeignClientsConfiguration.class) - protected static class SampleConfiguration1 { - - } - - @Test - public void testCustomLogger() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleConfiguration2.class); - FeignLoggerFactory loggerFactory = context.getBean(FeignLoggerFactory.class); - assertNotNull(loggerFactory); - Logger logger = loggerFactory.create(Object.class); - assertNotNull(logger); - assertTrue(logger instanceof LoggerImpl1); - context.close(); - } - - @Configuration - @Import(FeignClientsConfiguration.class) - protected static class SampleConfiguration2 { - - @Bean - public Logger logger() { - return new LoggerImpl1(); - } - - } - - static class LoggerImpl1 extends Logger { - - @Override - protected void log(String arg0, String arg1, Object... arg2) { - // noop - } - - } - - @Test - public void testCustomLoggerFactory() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleConfiguration3.class); - FeignLoggerFactory loggerFactory = context.getBean(FeignLoggerFactory.class); - assertNotNull(loggerFactory); - assertTrue(loggerFactory instanceof LoggerFactoryImpl); - Logger logger = loggerFactory.create(Object.class); - assertNotNull(logger); - assertTrue(logger instanceof LoggerImpl2); - context.close(); - } - - @Configuration - @Import(FeignClientsConfiguration.class) - protected static class SampleConfiguration3 { - - @Bean - public FeignLoggerFactory feignLoggerFactory() { - return new LoggerFactoryImpl(); - } - - } - - static class LoggerFactoryImpl implements FeignLoggerFactory { - - @Override - public Logger create(Class type) { - return new LoggerImpl2(); - } - - } - - static class LoggerImpl2 extends Logger { - - @Override - protected void log(String arg0, String arg1, Object... arg2) { - // noop - } - - } - -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignOkHttpConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignOkHttpConfigurationTests.java deleted file mode 100644 index a55d758c1..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignOkHttpConfigurationTests.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2013-2018 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.feign; - -import okhttp3.OkHttpClient; - -import java.lang.reflect.Field; -import javax.net.ssl.HostnameVerifier; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.commons.httpclient.OkHttpClientFactory; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.cloud.test.ModifiedClassPathRunner; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.util.ReflectionUtils; - -/** - * @author Ryan Baxter - */ -@RunWith(ModifiedClassPathRunner.class) -@ClassPathExclusions({ "ribbon-loadbalancer-{version:\\d.*}.jar" }) -public class FeignOkHttpConfigurationTests { - - private ConfigurableApplicationContext context; - - @Before - public void setUp() { - context = new SpringApplicationBuilder().properties("debug=true","feign.httpclient.disableSslValidation=true", - "feign.okhttp.enabled=true", "feign.httpclient.enabled=false").web(false) - .sources(HttpClientConfiguration.class, FeignAutoConfiguration.class).run(); - } - - @After - public void tearDown() { - if(context != null) { - context.close(); - } - } - - @Test - public void disableSslTest() throws Exception { - OkHttpClient httpClient = context.getBean(OkHttpClient.class); - HostnameVerifier hostnameVerifier = (HostnameVerifier)this.getField(httpClient, "hostnameVerifier"); - Assert.assertTrue(OkHttpClientFactory.TrustAllHostnames.class.isInstance(hostnameVerifier)); - } - - protected Object getField(Object target, String name) { - Field field = ReflectionUtils.findField(target.getClass(), name); - ReflectionUtils.makeAccessible(field); - Object value = ReflectionUtils.getField(field, target); - return value; - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/SpringDecoderTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/SpringDecoderTests.java deleted file mode 100644 index 5558eef0e..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/SpringDecoderTests.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright 2013-2015 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.feign; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = SpringDecoderTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = { - "spring.application.name=springdecodertest", "spring.jmx.enabled=false" }) -@DirtiesContext -public class SpringDecoderTests extends FeignClientFactoryBean { - - @Autowired - FeignContext context; - - @Value("${local.server.port}") - private int port = 0; - - public SpringDecoderTests() { - setName("test"); - } - - public TestClient testClient() { - return testClient(false); - } - - public TestClient testClient(boolean decode404) { - setType(this.getClass()); - setDecode404(decode404); - return feign(context).target(TestClient.class, "http://localhost:" + this.port); - } - - @Test - public void testResponseEntity() { - ResponseEntity response = testClient().getHelloResponse(); - assertNotNull("response was null", response); - assertEquals("wrong status code", HttpStatus.OK, response.getStatusCode()); - Hello hello = response.getBody(); - assertNotNull("hello was null", hello); - assertEquals("first hello didn't match", new Hello("hello world via response"), - hello); - } - - @Test - public void testSimpleType() { - Hello hello = testClient().getHello(); - assertNotNull("hello was null", hello); - assertEquals("first hello didn't match", new Hello("hello world 1"), hello); - } - - @Test - public void testUserParameterizedTypeDecode() { - List hellos = testClient().getHellos(); - assertNotNull("hellos was null", hellos); - assertEquals("hellos was not the right size", 2, hellos.size()); - assertEquals("first hello didn't match", new Hello("hello world 1"), - hellos.get(0)); - } - - @Test - public void testSimpleParameterizedTypeDecode() { - List hellos = testClient().getHelloStrings(); - assertNotNull("hellos was null", hellos); - assertEquals("hellos was not the right size", 2, hellos.size()); - assertEquals("first hello didn't match", "hello world 1", hellos.get(0)); - } - - @Test - @SuppressWarnings("unchecked") - public void testWildcardTypeDecode() { - ResponseEntity wildcard = testClient().getWildcard(); - assertNotNull("wildcard was null", wildcard); - assertEquals("wrong status code", HttpStatus.OK, wildcard.getStatusCode()); - Object wildcardBody = wildcard.getBody(); - assertNotNull("wildcardBody was null", wildcardBody); - assertTrue("wildcard not an instance of Map", wildcardBody instanceof Map); - Map hello = (Map) wildcardBody; - assertEquals("first hello didn't match", "wildcard", hello.get("message")); - } - - @Test - public void testResponseEntityVoid() { - ResponseEntity response = testClient().getHelloVoid(); - assertNotNull("response was null", response); - List headerVals = response.getHeaders().get("X-test-header"); - assertNotNull("headerVals was null", headerVals); - assertEquals("headerVals size was wrong", 1, headerVals.size()); - String header = headerVals.get(0); - assertEquals("header was wrong", "myval", header); - } - - @Test(expected = RuntimeException.class) - public void test404() { - testClient().getNotFound(); - } - - @Test - public void testDecodes404() { - final ResponseEntity response = testClient(true).getNotFound(); - assertNotNull("response was null", response); - assertNull("response body was not null", response.getBody()); - } - - public static class Hello { - private String message; - - public Hello() { - } - - public Hello(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Hello that = (Hello) o; - return Objects.equals(message, that.message); - } - - @Override - public int hashCode() { - return Objects.hash(message); - } - } - - protected interface TestClient { - @RequestMapping(method = RequestMethod.GET, value = "/helloresponse") - ResponseEntity getHelloResponse(); - - @RequestMapping(method = RequestMethod.GET, value = "/hellovoid") - ResponseEntity getHelloVoid(); - - @RequestMapping(method = RequestMethod.GET, value = "/hello") - Hello getHello(); - - @RequestMapping(method = RequestMethod.GET, value = "/hellos") - List getHellos(); - - @RequestMapping(method = RequestMethod.GET, value = "/hellostrings") - List getHelloStrings(); - - @RequestMapping(method = RequestMethod.GET, value = "/hellonotfound") - ResponseEntity getNotFound(); - - @GetMapping("/helloWildcard") - ResponseEntity getWildcard(); - } - - @Configuration - @EnableAutoConfiguration - @RestController - protected static class Application implements TestClient { - - @Override - public ResponseEntity getHelloResponse() { - return ResponseEntity.ok(new Hello("hello world via response")); - } - - @Override - public ResponseEntity getHelloVoid() { - return ResponseEntity.noContent().header("X-test-header", "myval").build(); - } - - @Override - public Hello getHello() { - return new Hello("hello world 1"); - } - - @Override - public List getHellos() { - ArrayList hellos = new ArrayList<>(); - hellos.add(new Hello("hello world 1")); - hellos.add(new Hello("oi terra 2")); - return hellos; - } - - @Override - public List getHelloStrings() { - ArrayList hellos = new ArrayList<>(); - hellos.add("hello world 1"); - hellos.add("oi terra 2"); - return hellos; - } - - @Override - public ResponseEntity getNotFound() { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body((String) null); - } - - @Override - public ResponseEntity getWildcard() { - return ResponseEntity.ok(new Hello("wildcard")); - } - - } - -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/SpringRetryDisabledTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/SpringRetryDisabledTests.java deleted file mode 100644 index 11ca4d1bb..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/SpringRetryDisabledTests.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.feign; - -import java.util.Map; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration; -import org.springframework.cloud.netflix.feign.ribbon.CachingSpringLoadBalancerFactory; -import org.springframework.cloud.netflix.feign.ribbon.FeignLoadBalancer; -import org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientAutoConfiguration; -import org.springframework.cloud.netflix.feign.ribbon.RetryableFeignLoadBalancer; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.cloud.test.ModifiedClassPathRunner; -import org.springframework.context.ConfigurableApplicationContext; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.core.Is.is; - -/** - * @author Ryan Baxter - */ -@RunWith(ModifiedClassPathRunner.class) -@ClassPathExclusions({"spring-retry-*.jar", "spring-boot-starter-aop-*.jar"}) -public class SpringRetryDisabledTests { - - private ConfigurableApplicationContext context; - - @Before - public void setUp() { - context = new SpringApplicationBuilder().web(false) - .sources(RibbonAutoConfiguration.class, LoadBalancerAutoConfiguration.class, RibbonClientConfiguration.class, - FeignRibbonClientAutoConfiguration.class).run(); - } - - @After - public void tearDown() { - if(context != null) { - context.close(); - } - } - - @Test - public void testLoadBalancedRetryFactoryBean() throws Exception { - Map lbFactorys = context.getBeansOfType(CachingSpringLoadBalancerFactory.class); - assertThat(lbFactorys.values(), hasSize(1)); - FeignLoadBalancer lb =lbFactorys.values().iterator().next().create("foo"); - assertThat(lb, instanceOf(FeignLoadBalancer.class)); - assertThat(lb, is(not(instanceOf(RetryableFeignLoadBalancer.class)))); - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/SpringRetryEnabledTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/SpringRetryEnabledTests.java deleted file mode 100644 index 5a2eb5122..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/SpringRetryEnabledTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.feign; - -import java.util.Map; -import org.hamcrest.Matchers; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.BeansException; -import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.feign.ribbon.CachingSpringLoadBalancerFactory; -import org.springframework.cloud.netflix.feign.ribbon.FeignLoadBalancer; -import org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientAutoConfiguration; -import org.springframework.cloud.netflix.feign.ribbon.RetryableFeignLoadBalancer; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.instanceOf; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = {RibbonAutoConfiguration.class, RibbonClientConfiguration.class, LoadBalancerAutoConfiguration.class, - FeignRibbonClientAutoConfiguration.class, HttpClientConfiguration.class}) -public class SpringRetryEnabledTests implements ApplicationContextAware { - - private ApplicationContext context; - - @Test - public void testLoadBalancedRetryFactoryBean() throws Exception { - Map lbFactorys = context.getBeansOfType(CachingSpringLoadBalancerFactory.class); - assertThat(lbFactorys.values(), Matchers.hasSize(1)); - FeignLoadBalancer lb =lbFactorys.values().iterator().next().create("foo"); - assertThat(lb, instanceOf(RetryableFeignLoadBalancer.class)); - } - - @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { - this.context = context; - } -} \ No newline at end of file diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/beans/FeignClientTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/beans/FeignClientTests.java deleted file mode 100644 index 8e7432173..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/beans/FeignClientTests.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.beans; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Proxy; -import java.util.Map; -import java.util.Objects; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -/** - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = FeignClientTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = { - "spring.application.name=feignclienttest", - "logging.level.org.springframework.cloud.netflix.feign.valid=DEBUG", - "feign.httpclient.enabled=false", "feign.okhttp.enabled=false" }) -@DirtiesContext -public class FeignClientTests { - - @Value("${local.server.port}") - private int port = 0; - - @Autowired - private TestClient testClient; - - @Autowired - private ApplicationContext context; - - @Qualifier("uniquequalifier") - @Autowired - private org.springframework.cloud.netflix.feign.beans.extra.TestClient extraClient; - - @Configuration - @EnableAutoConfiguration - @RestController - @EnableFeignClients - protected static class Application { - - @RequestMapping(method = RequestMethod.GET, value = "/hello") - public Hello getHello() { - return new Hello("hello world 1"); - } - } - - public static class Hello { - private String message; - - public Hello() { - } - - public Hello(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Hello that = (Hello) o; - - return Objects.equals(message, that.message); - } - - @Override - public int hashCode() { - return message != null ? message.hashCode() : 0; - } - } - - @Test - public void testAnnnotations() throws Exception { - Map beans = this.context - .getBeansWithAnnotation(FeignClient.class); - assertTrue("Wrong clients: " + beans, - beans.containsKey(TestClient.class.getName())); - } - - @Test - public void testClient() { - assertNotNull("testClient was null", this.testClient); - assertNotNull("testClient was null", this.extraClient); - assertTrue("testClient is not a java Proxy", - Proxy.isProxyClass(this.testClient.getClass())); - InvocationHandler invocationHandler = Proxy.getInvocationHandler(this.testClient); - assertNotNull("invocationHandler was null", invocationHandler); - } - - @Configuration - public static class TestDefaultFeignConfig { - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/beans/TestClient.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/beans/TestClient.java deleted file mode 100644 index 955a3caa8..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/beans/TestClient.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.beans; - -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.cloud.netflix.feign.beans.FeignClientTests.Hello; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -@FeignClient(value = "localapp") -public interface TestClient { - @RequestMapping(method = RequestMethod.GET, value = "/hello") - Hello getHello(); -} \ No newline at end of file diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/beans/extra/TestClient.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/beans/extra/TestClient.java deleted file mode 100644 index 42676f683..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/beans/extra/TestClient.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.beans.extra; - -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.cloud.netflix.feign.beans.FeignClientTests.Hello; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -@FeignClient(value = "otherapp", qualifier = "uniquequalifier") -public interface TestClient { - @RequestMapping(method = RequestMethod.GET, value = "/hello") - Hello getHello(); -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/FeignAcceptEncodingTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/FeignAcceptEncodingTests.java deleted file mode 100644 index bd7f99569..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/FeignAcceptEncodingTests.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.encoding; - -import java.util.Collections; -import java.util.List; - -import com.netflix.loadbalancer.BaseLoadBalancer; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.Server; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.cloud.netflix.feign.encoding.app.client.InvoiceClient; -import org.springframework.cloud.netflix.feign.encoding.app.domain.Invoice; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -/** - * Tests the response compression. - * - * @author Jakub Narloch - */ -@SpringBootTest(classes = FeignAcceptEncodingTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = { - "feign.compression.response.enabled=true" }) -@RunWith(SpringRunner.class) -@DirtiesContext -public class FeignAcceptEncodingTests { - - @Autowired - private InvoiceClient invoiceClient; - - @Test - public void compressedResponse() { - - // when - final ResponseEntity> invoices = this.invoiceClient.getInvoices(); - - // then - assertNotNull(invoices); - assertEquals(HttpStatus.OK, invoices.getStatusCode()); - assertNotNull(invoices.getBody()); - assertEquals(100, invoices.getBody().size()); - - } - - @EnableFeignClients(clients = InvoiceClient.class) - @RibbonClient(name = "local", configuration = LocalRibbonClientConfiguration.class) - @SpringBootApplication(scanBasePackages = "org.springframework.cloud.netflix.feign.encoding.app") - public static class Application { - } - - @Configuration - static class LocalRibbonClientConfiguration { - - @Value("${local.server.port}") - private int port = 0; - - @Bean - public ILoadBalancer ribbonLoadBalancer() { - BaseLoadBalancer balancer = new BaseLoadBalancer(); - balancer.setServersList( - Collections.singletonList(new Server("localhost", this.port))); - return balancer; - } - } -} \ No newline at end of file diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/FeignContentEncodingTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/FeignContentEncodingTests.java deleted file mode 100644 index 372c35c71..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/FeignContentEncodingTests.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.encoding; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.util.Collections; -import java.util.List; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.cloud.netflix.feign.encoding.app.client.InvoiceClient; -import org.springframework.cloud.netflix.feign.encoding.app.domain.Invoice; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import com.netflix.loadbalancer.BaseLoadBalancer; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.Server; - -/** - * Tests the response compression. - * - * @author Jakub Narloch - */ -@SpringBootTest(classes = FeignContentEncodingTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = { - "feign.compression.request.enabled=true", - "hystrix.command.default.execution.isolation.strategy=SEMAPHORE", - "ribbon.OkToRetryOnAllOperations=false" }) -@RunWith(SpringJUnit4ClassRunner.class) -public class FeignContentEncodingTests { - - @Autowired - private InvoiceClient invoiceClient; - - @Test - public void compressedResponse() { - - // given - final List invoices = Invoices.createInvoiceList(50); - - // when - final ResponseEntity> response = this.invoiceClient - .saveInvoices(invoices); - - // then - assertNotNull(response); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertNotNull(response.getBody()); - assertEquals(invoices.size(), response.getBody().size()); - - } - - @EnableFeignClients(clients = InvoiceClient.class) - @RibbonClient(name = "local", configuration = LocalRibbonClientConfiguration.class) - @SpringBootApplication(scanBasePackages = "org.springframework.cloud.netflix.feign.encoding.app") - public static class Application { - } - - @Configuration - static class LocalRibbonClientConfiguration { - - @Value("${local.server.port}") - private int port = 0; - - @Bean - public ILoadBalancer ribbonLoadBalancer() { - BaseLoadBalancer balancer = new BaseLoadBalancer(); - balancer.setServersList( - Collections.singletonList(new Server("localhost", this.port))); - return balancer; - } - } -} \ No newline at end of file diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/Invoices.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/Invoices.java deleted file mode 100644 index 1bcfa9570..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/Invoices.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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.feign.encoding; - -import org.springframework.cloud.netflix.feign.encoding.app.domain.Invoice; - -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -/** - * Utility class used for testing. - * - * @author Jakub Narloch - */ -final class Invoices { - - public static List createInvoiceList(int count) { - final List 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; - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/app/client/InvoiceClient.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/app/client/InvoiceClient.java deleted file mode 100644 index bc0339762..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/app/client/InvoiceClient.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.encoding.app.client; - -import java.util.List; - -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.cloud.netflix.feign.encoding.app.domain.Invoice; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -/** - * Simple Feign client for retrieving the invoice list. - * - * @author Jakub Narloch - */ -@FeignClient("local") -public interface InvoiceClient { - - @RequestMapping(value = "invoices", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) - ResponseEntity> getInvoices(); - - @RequestMapping(value = "invoices", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - ResponseEntity> saveInvoices(List invoices); -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/app/domain/Invoice.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/app/domain/Invoice.java deleted file mode 100644 index 9bd28d8e9..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/app/domain/Invoice.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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.feign.encoding.app.domain; - -import java.math.BigDecimal; - -/** - * An Invoice model - used for testing. - * - * @author Jakub Narloch - */ -public class Invoice { - - private String title; - - private BigDecimal amount; - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public BigDecimal getAmount() { - return amount; - } - - public void setAmount(BigDecimal amount) { - this.amount = amount; - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/app/resource/InvoiceResource.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/app/resource/InvoiceResource.java deleted file mode 100644 index 80933f582..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/app/resource/InvoiceResource.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.feign.encoding.app.resource; - -import org.springframework.cloud.netflix.feign.encoding.app.domain.Invoice; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -/** - * An sample REST controller, that potentially returns large response - used for testing. - * - * @author Jakub Narloch - */ -@RestController -public class InvoiceResource { - - @RequestMapping(value = "invoices", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity> getInvoices() { - - return ResponseEntity.ok(createInvoiceList(100)); - } - - @RequestMapping(value = "invoices", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - ResponseEntity> saveInvoices(@RequestBody List invoices) { - - return ResponseEntity.ok(invoices); - } - - private List createInvoiceList(int count) { - final List 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; - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/invalid/FeignClientValidationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/invalid/FeignClientValidationTests.java deleted file mode 100644 index db6ed80ca..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/invalid/FeignClientValidationTests.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.invalid; - -import feign.Feign; -import feign.hystrix.FallbackFactory; -import feign.hystrix.HystrixFeign; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.cloud.netflix.feign.FeignAutoConfiguration; -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import static org.junit.Assert.assertNotNull; - -/** - * @author Dave Syer - */ -public class FeignClientValidationTests { - - @Rule - public ExpectedException expected = ExpectedException.none(); - - @Test - public void testNameAndValue() { - this.expected.expectMessage("only one is permitted"); - new AnnotationConfigApplicationContext(NameAndValueConfiguration.class); - } - - @Configuration - @Import(FeignAutoConfiguration.class) - @EnableFeignClients(clients = NameAndValueConfiguration.Client.class) - protected static class NameAndValueConfiguration { - - @FeignClient(value = "foo", name = "bar") - interface Client { - @RequestMapping(method = RequestMethod.GET, value = "/") - String get(); - } - - } - - @Test - public void testServiceIdAndValue() { - this.expected.expectMessage("only one is permitted"); - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( - NameAndValueConfiguration.class); - assertNotNull(context.getBean(NameAndServiceIdConfiguration.Client.class)); - context.close(); - } - - @Configuration - @Import(FeignAutoConfiguration.class) - @EnableFeignClients(clients = NameAndServiceIdConfiguration.Client.class) - protected static class NameAndServiceIdConfiguration { - - @FeignClient(serviceId = "foo", name = "bar") - interface Client { - @RequestMapping(method = RequestMethod.GET, value = "/") - String get(); - } - - } - - @Test - public void testNotLegalHostname() { - this.expected.expectMessage("not legal hostname (foo_bar)"); - new AnnotationConfigApplicationContext(BadHostnameConfiguration.class); - } - - @Configuration - @Import(FeignAutoConfiguration.class) - @EnableFeignClients(clients = BadHostnameConfiguration.Client.class) - protected static class BadHostnameConfiguration { - - @FeignClient("foo_bar") - interface Client { - @RequestMapping(method = RequestMethod.GET, value = "/") - String get(); - } - - } - - @Test - public void testMissingFallback() { - try ( - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( - MissingFallbackConfiguration.class)) { - this.expected.expectMessage("No fallback instance of type"); - assertNotNull(context.getBean(MissingFallbackConfiguration.Client.class)); - } - } - - @Configuration - @Import(FeignAutoConfiguration.class) - @EnableFeignClients(clients = MissingFallbackConfiguration.Client.class) - protected static class MissingFallbackConfiguration { - - @FeignClient(name = "foobar", url = "http://localhost", fallback = ClientFallback.class) - interface Client { - @RequestMapping(method = RequestMethod.GET, value = "/") - String get(); - } - - class ClientFallback implements Client { - @Override - public String get() { - return null; - } - } - - @Bean - public Feign.Builder feignBuilder() { - return HystrixFeign.builder(); - } - } - - @Test - public void testWrongFallbackType() { - try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( - WrongFallbackTypeConfiguration.class)) { - this.expected.expectMessage("Incompatible fallback instance"); - assertNotNull(context.getBean(WrongFallbackTypeConfiguration.Client.class)); - } - } - - @Configuration - @Import(FeignAutoConfiguration.class) - @EnableFeignClients(clients = WrongFallbackTypeConfiguration.Client.class) - protected static class WrongFallbackTypeConfiguration { - - @FeignClient(name = "foobar", url = "http://localhost", fallback = Dummy.class) - interface Client { - @RequestMapping(method = RequestMethod.GET, value = "/") - String get(); - } - - @Bean - Dummy dummy() { - return new Dummy(); - } - - class Dummy { - } - - @Bean - public Feign.Builder feignBuilder() { - return HystrixFeign.builder(); - } - - } - - @Test - public void testMissingFallbackFactory() { - try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( - MissingFallbackFactoryConfiguration.class)) { - this.expected.expectMessage("No fallbackFactory instance of type"); - assertNotNull(context.getBean(MissingFallbackFactoryConfiguration.Client.class)); - } - } - - @Configuration - @Import(FeignAutoConfiguration.class) - @EnableFeignClients(clients = MissingFallbackFactoryConfiguration.Client.class) - protected static class MissingFallbackFactoryConfiguration { - - @FeignClient(name = "foobar", url = "http://localhost", fallbackFactory = ClientFallback.class) - interface Client { - @RequestMapping(method = RequestMethod.GET, value = "/") - String get(); - } - - class ClientFallback implements FallbackFactory { - - @Override - public Client create(Throwable cause) { - return null; - } - } - - @Bean - public Feign.Builder feignBuilder() { - return HystrixFeign.builder(); - } - } - - @Test - public void testWrongFallbackFactoryType() { - try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( - WrongFallbackFactoryTypeConfiguration.class)) { - this.expected.expectMessage("Incompatible fallbackFactory instance"); - assertNotNull(context.getBean(WrongFallbackFactoryTypeConfiguration.Client.class)); - } - } - - @Configuration - @Import(FeignAutoConfiguration.class) - @EnableFeignClients(clients = WrongFallbackFactoryTypeConfiguration.Client.class) - protected static class WrongFallbackFactoryTypeConfiguration { - - @FeignClient(name = "foobar", url = "http://localhost", fallbackFactory = Dummy.class) - interface Client { - @RequestMapping(method = RequestMethod.GET, value = "/") - String get(); - } - - @Bean - Dummy dummy() { - return new Dummy(); - } - - class Dummy { - } - - @Bean - public Feign.Builder feignBuilder() { - return HystrixFeign.builder(); - } - - } - - @Test - public void testWrongFallbackFactoryGenericType() { - try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( - WrongFallbackFactoryGenericTypeConfiguration.class)) { - this.expected.expectMessage("Incompatible fallbackFactory instance"); - assertNotNull(context.getBean(WrongFallbackFactoryGenericTypeConfiguration.Client.class)); - } - } - - @Configuration - @Import(FeignAutoConfiguration.class) - @EnableFeignClients(clients = WrongFallbackFactoryGenericTypeConfiguration.Client.class) - protected static class WrongFallbackFactoryGenericTypeConfiguration { - - @FeignClient(name = "foobar", url = "http://localhost", fallbackFactory = ClientFallback.class) - interface Client { - @RequestMapping(method = RequestMethod.GET, value = "/") - String get(); - } - - @Bean - ClientFallback dummy() { - return new ClientFallback(); - } - - class ClientFallback implements FallbackFactory { - - @Override - public String create(Throwable cause) { - return "tryinToTrickYa"; - } - } - - @Bean - public Feign.Builder feignBuilder() { - return HystrixFeign.builder(); - } - - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/CachingSpringLoadBalancerFactoryTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/CachingSpringLoadBalancerFactoryTests.java deleted file mode 100644 index d86ed0877..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/CachingSpringLoadBalancerFactoryTests.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.ribbon; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.springframework.cloud.client.loadbalancer.LoadBalancedBackOffPolicyFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryListenerFactory; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicyFactory; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; - -import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * @author Spencer Gibb - */ -public class CachingSpringLoadBalancerFactoryTests { - - @Mock - private SpringClientFactory delegate; - - @Mock - private RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory; - - @Mock - private LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory; - - @Mock - private LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory; - - private CachingSpringLoadBalancerFactory factory; - - @Before - public void init() { - MockitoAnnotations.initMocks(this); - - IClientConfig config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.ConnectTimeout, 1000); - config.set(CommonClientConfigKey.ReadTimeout, 500); - - when(this.delegate.getClientConfig("client1")).thenReturn(config); - when(this.delegate.getClientConfig("client2")).thenReturn(config); - - this.factory = new CachingSpringLoadBalancerFactory(this.delegate, - loadBalancedRetryPolicyFactory); - } - - @Test - public void delegateCreatesWhenMissing() { - FeignLoadBalancer client = this.factory.create("client1"); - assertNotNull("client was null", client); - - verify(this.delegate, times(1)).getClientConfig("client1"); - } - - @Test - public void cacheWorks() { - FeignLoadBalancer client = this.factory.create("client2"); - assertNotNull("client was null", client); - - client = this.factory.create("client2"); - assertNotNull("client was null", client); - - verify(this.delegate, times(1)).getClientConfig("client2"); - } - - @Test - public void delegateCreatesWithNoRetry() { - IClientConfig config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.ConnectTimeout, 1000); - config.set(CommonClientConfigKey.ReadTimeout, 500); - when(this.delegate.getClientConfig("retry")).thenReturn(config); - CachingSpringLoadBalancerFactory factory = new CachingSpringLoadBalancerFactory(this.delegate); - FeignLoadBalancer client = this.factory.create("retry"); - assertNotNull("client was null", client); - } - - @Test - public void delegateCreatesWithRetry() { - IClientConfig config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.ConnectTimeout, 1000); - config.set(CommonClientConfigKey.ReadTimeout, 500); - when(this.delegate.getClientConfig("retry")).thenReturn(config); - CachingSpringLoadBalancerFactory factory = new CachingSpringLoadBalancerFactory( - this.delegate, loadBalancedRetryPolicyFactory, false); - FeignLoadBalancer client = this.factory.create("retry"); - assertNotNull("client was null", client); - } - - @Test - public void delegateCreatesWithBackOff() { - IClientConfig config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.ConnectTimeout, 1000); - config.set(CommonClientConfigKey.ReadTimeout, 500); - when(this.delegate.getClientConfig("retry")).thenReturn(config); - CachingSpringLoadBalancerFactory factory = new CachingSpringLoadBalancerFactory( - this.delegate, loadBalancedRetryPolicyFactory, loadBalancedBackOffPolicyFactory); - FeignLoadBalancer client = this.factory.create("retry"); - assertNotNull("client was null", client); - } - - @Test - public void delegateCreatesWithRetryListener() { - IClientConfig config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.ConnectTimeout, 1000); - config.set(CommonClientConfigKey.ReadTimeout, 500); - when(this.delegate.getClientConfig("retry")).thenReturn(config); - CachingSpringLoadBalancerFactory factory = new CachingSpringLoadBalancerFactory( - this.delegate, loadBalancedRetryPolicyFactory, loadBalancedBackOffPolicyFactory, loadBalancedRetryListenerFactory); - FeignLoadBalancer client = this.factory.create("retry"); - assertNotNull("client was null", client); - } - -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignLoadBalancerTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignLoadBalancerTests.java deleted file mode 100644 index 4e468ca33..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignLoadBalancerTests.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * 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.feign.ribbon; - -import java.net.URI; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.springframework.cloud.netflix.feign.ribbon.FeignLoadBalancer.RibbonRequest; -import org.springframework.cloud.netflix.feign.ribbon.FeignLoadBalancer.RibbonResponse; -import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; - -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.Server; - -import feign.Client; -import feign.Request; -import feign.RequestTemplate; -import feign.Response; -import feign.Request.Options; - -import static com.netflix.client.config.CommonClientConfigKey.ConnectTimeout; -import static com.netflix.client.config.CommonClientConfigKey.IsSecure; -import static com.netflix.client.config.CommonClientConfigKey.MaxAutoRetries; -import static com.netflix.client.config.CommonClientConfigKey.MaxAutoRetriesNextServer; -import static com.netflix.client.config.CommonClientConfigKey.OkToRetryOnAllOperations; -import static com.netflix.client.config.CommonClientConfigKey.ReadTimeout; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_MAX_AUTO_RETRIES; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_MAX_AUTO_RETRIES_NEXT_SERVER; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.when; - -public class FeignLoadBalancerTests { - - @Mock - private Client delegate; - @Mock - private ILoadBalancer lb; - @Mock - private IClientConfig config; - - private FeignLoadBalancer feignLoadBalancer; - - private ServerIntrospector inspector = new DefaultServerIntrospector(); - - private Integer defaultConnectTimeout = 10000; - private Integer defaultReadTimeout = 10000; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - when(this.config.get(MaxAutoRetries, DEFAULT_MAX_AUTO_RETRIES)).thenReturn(1); - when(this.config.get(MaxAutoRetriesNextServer, - DEFAULT_MAX_AUTO_RETRIES_NEXT_SERVER)).thenReturn(1); - when(this.config.get(OkToRetryOnAllOperations, eq(anyBoolean()))) - .thenReturn(true); - when(this.config.get(ConnectTimeout)).thenReturn(this.defaultConnectTimeout); - when(this.config.get(ReadTimeout)).thenReturn(this.defaultReadTimeout); - when(this.config.get(OkToRetryOnAllOperations, false)).thenReturn(true); - } - - @Test - public void testUriInsecure() throws Exception { - when(this.config.get(IsSecure)).thenReturn(false); - - this.feignLoadBalancer = new FeignLoadBalancer(this.lb, this.config, - this.inspector); - Request request = new RequestTemplate().method("GET").append("http://foo/") - .request(); - RibbonRequest ribbonRequest = new RibbonRequest(this.delegate, request, - new URI(request.url())); - - Response response = Response.create(200, "Test", - Collections.> emptyMap(), new byte[0]); - when(this.delegate.execute(any(Request.class), any(Options.class))) - .thenReturn(response); - - RibbonResponse resp = this.feignLoadBalancer.execute(ribbonRequest, null); - - assertThat(resp.getRequestedURI(), is(new URI("http://foo/"))); - } - - @Test - public void testSecureUriFromClientConfig() throws Exception { - when(this.config.get(IsSecure)).thenReturn(true); - this.feignLoadBalancer = new FeignLoadBalancer(this.lb, this.config, - this.inspector); - Server server = new Server("foo", 7777); - URI uri = this.feignLoadBalancer.reconstructURIWithServer(server, - new URI("http://foo/")); - assertThat(uri, is(new URI("https://foo:7777/"))); - } - - @Test - public void testInsecureUriFromInsecureClientConfigToSecureServerIntrospector() - throws Exception { - when(this.config.get(IsSecure)).thenReturn(false); - this.feignLoadBalancer = new FeignLoadBalancer(this.lb, this.config, - new ServerIntrospector() { - @Override - public boolean isSecure(Server server) { - return true; - } - - @Override - public Map getMetadata(Server server) { - return null; - } - }); - Server server = new Server("foo", 7777); - URI uri = this.feignLoadBalancer.reconstructURIWithServer(server, - new URI("http://foo/")); - assertThat(uri, is(new URI("http://foo:7777/"))); - } - - @Test - public void testSecureUriFromClientConfigOverride() throws Exception { - this.feignLoadBalancer = new FeignLoadBalancer(this.lb, this.config, - this.inspector); - Server server = Mockito.mock(Server.class); - when(server.getPort()).thenReturn(443); - when(server.getHost()).thenReturn("foo"); - URI uri = this.feignLoadBalancer.reconstructURIWithServer(server, - new URI("http://bar/")); - assertThat(uri, is(new URI("https://foo:443/"))); - } - - @Test - public void testRibbonRequestURLEncode() throws Exception { - String url = "http://foo/?name=%7bcookie";//name={cookie - Request request = Request.create("GET",url,new HashMap(),null,null); - - assertThat(request.url(),is(url)); - - RibbonRequest ribbonRequest = new RibbonRequest(this.delegate,request,new URI(request.url())); - - Request cloneRequest = ribbonRequest.toRequest(); - - assertThat(cloneRequest.url(),is(url)); - - } - -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientPathTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientPathTests.java deleted file mode 100644 index 3946c2564..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientPathTests.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright 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. - */ - -package org.springframework.cloud.netflix.feign.ribbon; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; - -/** - * @author Venil Noronha - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = FeignRibbonClientPathTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT,value = { - "spring.application.name=feignribbonclientpathtest", - "feign.okhttp.enabled=false", - "feign.httpclient.enabled=false", - "feign.hystrix.enabled=false", - "test.path.prefix=/base/path" // For pathWithPlaceholder test - } -) -@DirtiesContext -public class FeignRibbonClientPathTests { - - @Value("${local.server.port}") - private int port = 0; - - @Autowired - private TestClient1 testClient1; - - @Autowired - private TestClient2 testClient2; - - @Autowired - private TestClient3 testClient3; - - @Autowired - private TestClient4 testClient4; - - @Autowired - private TestClient5 testClient5; - - protected interface TestClient { - - @RequestMapping(method = RequestMethod.GET, value = "/hello") - Hello getHello(); - - } - - @FeignClient(name = "localapp", path = "/base/path") - protected interface TestClient1 extends TestClient { } - - @FeignClient(name = "localapp", path = "base/path") - protected interface TestClient2 extends TestClient { } - - @FeignClient(name = "localapp", path = "base/path/") - protected interface TestClient3 extends TestClient { } - - @FeignClient(name = "localapp", path = "/base/path/") - protected interface TestClient4 extends TestClient { } - - @FeignClient(name = "localapp", path = "${test.path.prefix}") - protected interface TestClient5 extends TestClient { } - - @Configuration - @EnableAutoConfiguration - @RestController - @RequestMapping("/base/path") - @EnableFeignClients(clients = { - TestClient1.class, TestClient2.class, TestClient3.class, TestClient4.class, - TestClient5.class - }) - @RibbonClient(name = "localapp", configuration = LocalRibbonClientConfiguration.class) - public static class Application { - - @RequestMapping(method = RequestMethod.GET, value = "/hello") - public Hello getHello() { - return new Hello("hello world"); - } - - } - - @Test - public void pathWithLeadingButNotTrailingSlash() { - testClientPath(this.testClient1); - } - - @Test - public void pathWithoutLeadingAndTrailingSlash() { - testClientPath(this.testClient2); - } - - @Test - public void pathWithoutLeadingButTrailingSlash() { - testClientPath(this.testClient3); - } - - @Test - public void pathWithLeadingAndTrailingSlash() { - testClientPath(this.testClient4); - } - - @Test - public void pathWithPlaceholder() { - testClientPath(this.testClient5); - } - - private void testClientPath(TestClient testClient) { - Hello hello = testClient.getHello(); - assertNotNull("Object returned was null", hello); - assertEquals("Response object value didn't match", "hello world", - hello.getMessage()); - } - - public static class Hello { - private String message; - - public Hello() {} - - public Hello(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - } - - @Configuration - public static class LocalRibbonClientConfiguration { - - @Value("${local.server.port}") - private int port = 0; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientRetryTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientRetryTests.java deleted file mode 100644 index 3e79c91fa..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientRetryTests.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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.feign.ribbon; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Proxy; -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -/** - * Tests the Feign Retryer, not ribbon retry. - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@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"}) -@DirtiesContext -public class FeignRibbonClientRetryTests { - - @Value("${local.server.port}") - private int port = 0; - - @Autowired - private TestClient testClient; - - @FeignClient("localapp") - protected interface TestClient { - @RequestMapping(method = RequestMethod.GET, value = "/hello") - Hello getHello(); - - @RequestMapping(method = RequestMethod.GET, value = "/retryme") - int retryMe(); - } - - @Configuration - @EnableAutoConfiguration - @RestController - @EnableFeignClients(clients = TestClient.class) - @RibbonClient(name = "localapp", configuration = LocalRibbonClientConfiguration.class) - public static class Application { - - private AtomicInteger retries = new AtomicInteger(1); - - @RequestMapping(method = RequestMethod.GET, value = "/hello") - public Hello getHello() { - return new Hello("hello world 1"); - } - - @RequestMapping(method = RequestMethod.GET, value = "/retryme") - public int retryMe() { - return this.retries.getAndIncrement(); - } - - } - - @Test - public void testClient() { - assertNotNull("testClient was null", this.testClient); - assertTrue("testClient is not a java Proxy", - Proxy.isProxyClass(this.testClient.getClass())); - InvocationHandler invocationHandler = Proxy.getInvocationHandler(this.testClient); - assertNotNull("invocationHandler was null", invocationHandler); - } - - @Test - public void testRetries() { - int retryMe = this.testClient.retryMe(); - assertEquals("retryCount didn't match", retryMe, 1); - // TODO: not sure how to verify retry happens. Debugging through it, it works - // maybe the assertEquals above is enough because of the bogus servers - } - - public static class Hello { - private String message; - - public Hello() { - } - - public Hello(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - } -} - -// Load balancer with fixed server list for "local" pointing to localhost -// some bogus servers are thrown in to test retry -@Configuration -class LocalRibbonClientConfiguration { - - @Value("${local.server.port}") - private int port = 0; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("mybadhost", 80), - new Server("mybadhost2", 10002), - new Server("mybadhost3", 10003), new Server("localhost", this.port)); - } - -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientTests.java deleted file mode 100644 index 7d0d45781..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientTests.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.ribbon; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.AbstractLoadBalancer; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.LoadBalancerStats; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerStats; -import feign.Client; -import feign.Request; -import feign.Request.Options; -import feign.RequestTemplate; -import org.hamcrest.CustomMatcher; -import org.junit.Before; -import org.junit.Test; -import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicyFactory; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * @author Dave Syer - * @author Spencer Gibb - */ -public class FeignRibbonClientTests { - - private AbstractLoadBalancer loadBalancer = mock(AbstractLoadBalancer.class); - private Client delegate = mock(Client.class); - private RibbonLoadBalancedRetryPolicyFactory retryPolicyFactory = mock(RibbonLoadBalancedRetryPolicyFactory.class); - - private SpringClientFactory factory = new SpringClientFactory() { - @Override - public IClientConfig getClientConfig(String name) { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.ConnectTimeout, 1000); - config.set(CommonClientConfigKey.ReadTimeout, 500); - return config; - } - - @Override - public C getInstance(String name, Class type) { - if (type.isAssignableFrom(ServerIntrospector.class)) { - @SuppressWarnings("unchecked") - C instance = (C) new DefaultServerIntrospector(); - return instance; - } - return null; - } - - @Override - public ILoadBalancer getLoadBalancer(String name) { - return FeignRibbonClientTests.this.loadBalancer; - } - }; - - // Even though we don't maintain FeignRibbonClient, keep these tests - // around to make sure the expected behaviour doesn't break - private Client client = new LoadBalancerFeignClient(this.delegate, new CachingSpringLoadBalancerFactory(this.factory, - retryPolicyFactory), this.factory); - - @Before - public void init() { - when(this.loadBalancer.chooseServer(any())).thenReturn( - new Server("foo.com", 8000)); - //to fix NPE - LoadBalancerStats stats = mock(LoadBalancerStats.class); - when(this.loadBalancer.getLoadBalancerStats()).thenReturn(stats); - when(stats.getSingleServerStat(any(Server.class))).thenReturn(mock(ServerStats.class)); - } - - @Test - public void remoteRequestIsSent() throws Exception { - Request request = new RequestTemplate().method("GET").append("http://foo/") - .request(); - this.client.execute(request, new Options()); - RequestMatcher matcher = new RequestMatcher("http://foo.com:8000/"); - /*FIXME verify(this.delegate).execute(argThat(matcher), - any(Options.class));*/ - } - - @Test - public void remoteRequestIsSecure() throws Exception { - Request request = new RequestTemplate().method("GET").append("https://foo/") - .request(); - this.client.execute(request, new Options()); - RequestMatcher matcher = new RequestMatcher("https://foo.com:8000/"); - /*FIXME verify(this.delegate).execute(argThat(matcher), - any(Options.class));*/ - } - - private final static class RequestMatcher extends CustomMatcher { - private String url; - - private RequestMatcher(String url) { - super("request has URI: " + url); - this.url = url; - } - - @Override - public boolean matches(Object item) { - Request request = (Request) item; - return request.url().equals(this.url); - } - } - -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonHttpClientConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonHttpClientConfigurationTests.java deleted file mode 100644 index 0c6905d19..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonHttpClientConfigurationTests.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2013-2018 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.feign.ribbon; - -import java.lang.reflect.Field; -import javax.net.ssl.SSLContextSpi; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.X509TrustManager; -import org.apache.http.config.Lookup; -import org.apache.http.conn.HttpClientConnectionManager; -import org.apache.http.conn.socket.ConnectionSocketFactory; -import org.apache.http.impl.conn.DefaultHttpClientConnectionOperator; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.ReflectionUtils; -import org.springframework.web.bind.annotation.RestController; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = FeignRibbonHttpClientConfigurationTests.Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = {"debug=true","feign.httpclient.disableSslValidation=true"}) -public class FeignRibbonHttpClientConfigurationTests { - - @Autowired - HttpClientConnectionManager connectionManager; - - @Test - public void disableSslTest() throws Exception { - Lookup socketFactoryRegistry = getConnectionSocketFactoryLookup(connectionManager); - assertNotNull(socketFactoryRegistry.lookup("https")); - assertNull(this.getX509TrustManager(socketFactoryRegistry).getAcceptedIssuers()); - } - - private Lookup getConnectionSocketFactoryLookup(HttpClientConnectionManager connectionManager) { - DefaultHttpClientConnectionOperator connectionOperator = (DefaultHttpClientConnectionOperator)this.getField(connectionManager, "connectionOperator"); - return (Lookup)this.getField(connectionOperator, "socketFactoryRegistry"); - } - - private X509TrustManager getX509TrustManager(Lookup socketFactoryRegistry) { - ConnectionSocketFactory connectionSocketFactory = (ConnectionSocketFactory)socketFactoryRegistry.lookup("https"); - SSLSocketFactory sslSocketFactory = (SSLSocketFactory)this.getField(connectionSocketFactory, "socketfactory"); - SSLContextSpi sslContext = (SSLContextSpi)this.getField(sslSocketFactory, "context"); - return (X509TrustManager)this.getField(sslContext, "trustManager"); - } - - protected Object getField(Object target, String name) { - Field field = ReflectionUtils.findField(target.getClass(), name); - ReflectionUtils.makeAccessible(field); - Object value = ReflectionUtils.getField(field, target); - return value; - } - - @Configuration - @EnableAutoConfiguration - @RestController - public static class Application { - public static void main(String[] args) { - new SpringApplicationBuilder(FeignRibbonClientRetryTests.Application.class) - .run(args); - } - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonOkHttpClientConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonOkHttpClientConfigurationTests.java deleted file mode 100644 index cdece199f..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonOkHttpClientConfigurationTests.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2013-2018 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.feign.ribbon; - -import okhttp3.OkHttpClient; - -import java.lang.reflect.Field; -import javax.net.ssl.HostnameVerifier; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.httpclient.OkHttpClientFactory; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.ReflectionUtils; -import org.springframework.web.bind.annotation.RestController; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = FeignRibbonOkHttpClientConfigurationTests.Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = {"debug=true","feign.httpclient.disableSslValidation=true", - "feign.okhttp.enabled=true", "feign.httpclient.enabled=false"}) -public class FeignRibbonOkHttpClientConfigurationTests { - - @Autowired - OkHttpClient httpClient; - - @Test - public void disableSslTest() throws Exception { - HostnameVerifier hostnameVerifier = (HostnameVerifier)this.getField(httpClient, "hostnameVerifier"); - Assert.assertTrue(OkHttpClientFactory.TrustAllHostnames.class.isInstance(hostnameVerifier)); - } - - protected Object getField(Object target, String name) { - Field field = ReflectionUtils.findField(target.getClass(), name); - ReflectionUtils.makeAccessible(field); - Object value = ReflectionUtils.getField(field, target); - return value; - } - - @Configuration - @EnableAutoConfiguration - @RestController - public static class Application { - public static void main(String[] args) { - new SpringApplicationBuilder(FeignRibbonClientRetryTests.Application.class) - .run(args); - } - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/LoadBalancerFeignClientOverrideTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/LoadBalancerFeignClientOverrideTests.java deleted file mode 100644 index 0efae7be7..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/LoadBalancerFeignClientOverrideTests.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.ribbon; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.cloud.netflix.feign.FeignContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RequestMapping; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.IClientConfig; - -import feign.Request; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = LoadBalancerFeignClientOverrideTests.TestConfiguration.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = { - "spring.application.name=loadBalancerFeignClientTests", - "feign.httpclient.enabled=false", "feign.okhttp.enabled=false" }) -@DirtiesContext -public class LoadBalancerFeignClientOverrideTests { - - @Autowired - private FeignContext context; - - @Test - public void overrideRequestOptions() { - // specific ribbon 'bar' configuration via spring bean - Request.Options barOptions = this.context.getInstance("bar", - Request.Options.class); - assertEquals(1, barOptions.connectTimeoutMillis()); - assertEquals(2, barOptions.readTimeoutMillis()); - assertOptions(barOptions, "bar", 1, 2); - - // specific ribbon 'foo' configuration via application.yml - Request.Options fooOptions = this.context.getInstance("foo", - Request.Options.class); - assertEquals(LoadBalancerFeignClient.DEFAULT_OPTIONS, fooOptions); - assertOptions(fooOptions, "foo", 7, 17); - - // generic ribbon default configuration - Request.Options bazOptions = this.context.getInstance("baz", - Request.Options.class); - assertEquals(LoadBalancerFeignClient.DEFAULT_OPTIONS, bazOptions); - assertOptions(bazOptions, "baz", 3001, 60001); - } - - void assertOptions(Request.Options options, String name, int expectedConnect, - int expectedRead) { - LoadBalancerFeignClient client = this.context.getInstance(name, - LoadBalancerFeignClient.class); - IClientConfig config = client.getClientConfig(options, name); - assertEquals("connect was wrong for " + name, expectedConnect, - config.get(CommonClientConfigKey.ConnectTimeout, -1).intValue()); - assertEquals("read was wrong for " + name, expectedRead, - config.get(CommonClientConfigKey.ReadTimeout, -1).intValue()); - } - - @Configuration - @EnableFeignClients(clients = { FooClient.class, BarClient.class, BazClient.class }) - @EnableAutoConfiguration - protected static class TestConfiguration { - } - - @FeignClient(value = "foo", configuration = FooConfiguration.class) - interface FooClient { - @RequestMapping("/") - String get(); - - } - - public static class FooConfiguration { - } - - @FeignClient(value = "bar", configuration = BarConfiguration.class) - interface BarClient { - @RequestMapping("/") - String get(); - } - - public static class BarConfiguration { - @Bean - public Request.Options feignRequestOptions() { - return new Request.Options(1, 2); - } - } - - @FeignClient("baz") - interface BazClient { - @RequestMapping("/") - String get(); - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/RetryableFeignLoadBalancerTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/RetryableFeignLoadBalancerTests.java deleted file mode 100644 index e00af80cc..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/RetryableFeignLoadBalancerTests.java +++ /dev/null @@ -1,525 +0,0 @@ -/* - * 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.feign.ribbon; - -import feign.Client; -import feign.Request; -import feign.Response; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancedBackOffPolicyFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryListenerFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory; -import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicy; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicyFactory; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.http.HttpRequest; -import org.springframework.retry.RetryCallback; -import org.springframework.retry.RetryContext; -import org.springframework.retry.RetryListener; -import org.springframework.retry.TerminatedRetryException; -import org.springframework.retry.backoff.BackOffContext; -import org.springframework.retry.backoff.BackOffInterruptedException; -import org.springframework.retry.backoff.BackOffPolicy; - -import com.netflix.client.DefaultLoadBalancerRetryHandler; -import com.netflix.client.RequestSpecificRetryHandler; -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.Server; - -import static com.netflix.client.config.CommonClientConfigKey.ConnectTimeout; -import static com.netflix.client.config.CommonClientConfigKey.MaxAutoRetries; -import static com.netflix.client.config.CommonClientConfigKey.MaxAutoRetriesNextServer; -import static com.netflix.client.config.CommonClientConfigKey.OkToRetryOnAllOperations; -import static com.netflix.client.config.CommonClientConfigKey.ReadTimeout; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_MAX_AUTO_RETRIES; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_MAX_AUTO_RETRIES_NEXT_SERVER; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * @author Ryan Baxter - * @author Gang Li - */ -public class RetryableFeignLoadBalancerTests { - @Mock - private ILoadBalancer lb; - @Mock - private IClientConfig config; - private ServerIntrospector inspector = new DefaultServerIntrospector(); - private LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory = - new LoadBalancedBackOffPolicyFactory.NoBackOffPolicyFactory(); - - private Integer defaultConnectTimeout = 10000; - private Integer defaultReadTimeout = 10000; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - when(this.config.get(MaxAutoRetries, DEFAULT_MAX_AUTO_RETRIES)).thenReturn(1); - when(this.config.get(MaxAutoRetriesNextServer, - DEFAULT_MAX_AUTO_RETRIES_NEXT_SERVER)).thenReturn(1); - when(this.config.get(OkToRetryOnAllOperations, eq(anyBoolean()))) - .thenReturn(true); - when(this.config.get(ConnectTimeout)).thenReturn(this.defaultConnectTimeout); - when(this.config.get(ReadTimeout)).thenReturn(this.defaultReadTimeout); - when(this.config.get(OkToRetryOnAllOperations, false)).thenReturn(true); - } - - @Test - public void executeNoFailure() throws Exception { - RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config); - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class)); - IClientConfig config = mock(IClientConfig.class); - doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt()); - doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(true).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false)); - doReturn(defaultConnectTimeout).when(config).get(eq(CommonClientConfigKey.ConnectTimeout)); - doReturn(defaultReadTimeout).when(config).get(eq(CommonClientConfigKey.ReadTimeout)); - doReturn("404,502,foo, ,").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq("")); - doReturn(config).when(clientFactory).getClientConfig(eq("default")); - RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory); - HttpRequest springRequest = mock(HttpRequest.class); - Request feignRequest = Request.create("GET", "http://foo", new HashMap>(), - new byte[]{}, StandardCharsets.UTF_8); - Client client = mock(Client.class); - FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo")); - Response response = Response.builder().status(200).headers(new HashMap>()).build(); - doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class)); - RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory, - loadBalancedBackOffPolicyFactory); - FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null); - assertEquals(200, ribbonResponse.toResponse().status()); - verify(client, times(1)).execute(any(Request.class), any(Request.Options.class)); - } - - @Test - public void executeNeverRetry() throws Exception { - HttpRequest springRequest = mock(HttpRequest.class); - Request feignRequest = Request.create("GET", "http://foo", new HashMap>(), - new byte[]{}, StandardCharsets.UTF_8); - Client client = mock(Client.class); - FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo")); - doThrow(new IOException("boom")).when(client).execute(any(Request.class), any(Request.Options.class)); - RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, new LoadBalancedRetryPolicyFactory() { - @Override - public LoadBalancedRetryPolicy create(String s, ServiceInstanceChooser serviceInstanceChooser) { - return null; - } - }, loadBalancedBackOffPolicyFactory); - try { - feignLb.execute(request, null); - } catch(Exception e) { - assertThat(e, instanceOf(IOException.class)); - } finally { - verify(client, times(1)).execute(any(Request.class), any(Request.Options.class)); - } - } - - @Test - public void executeRetry() throws Exception { - RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config); - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - IClientConfig config = mock(IClientConfig.class); - doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt()); - doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(true).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false)); - doReturn(defaultConnectTimeout).when(config).get(eq(CommonClientConfigKey.ConnectTimeout)); - doReturn(defaultReadTimeout).when(config).get(eq(CommonClientConfigKey.ReadTimeout)); - doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq("")); - doReturn(config).when(clientFactory).getClientConfig(eq("default")); - doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class)); - RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory); - HttpRequest springRequest = mock(HttpRequest.class); - Request feignRequest = Request.create("GET", "http://foo", new HashMap>(), - new byte[]{}, StandardCharsets.UTF_8); - Client client = mock(Client.class); - FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo")); - Response response = Response.builder().status(200).headers(new HashMap>()).build(); - doThrow(new IOException("boom")).doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class)); - MyBackOffPolicyFactory backOffPolicyFactory = new MyBackOffPolicyFactory(); - RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory, - backOffPolicyFactory); - FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null); - assertEquals(200, ribbonResponse.toResponse().status()); - verify(client, times(2)).execute(any(Request.class), any(Request.Options.class)); - assertEquals(1, backOffPolicyFactory.getCount()); - } - - @Test - public void executeRetryOnStatusCode() throws Exception { - RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config); - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - IClientConfig config = mock(IClientConfig.class); - doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt()); - doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(true).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false)); - doReturn(defaultConnectTimeout).when(config).get(eq(CommonClientConfigKey.ConnectTimeout)); - doReturn(defaultReadTimeout).when(config).get(eq(CommonClientConfigKey.ReadTimeout)); - doReturn("404").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq("")); - doReturn(config).when(clientFactory).getClientConfig(eq("default")); - doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class)); - RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory); - HttpRequest springRequest = mock(HttpRequest.class); - Request feignRequest = Request.create("GET", "http://foo", new HashMap>(), - new byte[]{}, StandardCharsets.UTF_8); - Client client = mock(Client.class); - FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo")); - Response response = Response.builder().status(200).headers(new HashMap>()).build(); - Response fourOFourResponse = Response.builder().status(404).headers(new HashMap>()).build(); - doReturn(fourOFourResponse).doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class)); - MyBackOffPolicyFactory backOffPolicyFactory = new MyBackOffPolicyFactory(); - RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory, - backOffPolicyFactory); - FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null); - assertEquals(200, ribbonResponse.toResponse().status()); - verify(client, times(2)).execute(any(Request.class), any(Request.Options.class)); - assertEquals(1, backOffPolicyFactory.getCount()); - } - - @Test - public void getRequestSpecificRetryHandler() throws Exception { - RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config); - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class)); - RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory); - HttpRequest springRequest = mock(HttpRequest.class); - Request feignRequest = Request.create("GET", "http://foo", new HashMap>(), - new byte[]{}, StandardCharsets.UTF_8); - Client client = mock(Client.class); - FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo")); - Response response = Response.builder().status(200).headers(new HashMap>()).build(); - doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class)); - RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory, - loadBalancedBackOffPolicyFactory); - RequestSpecificRetryHandler retryHandler = feignLb.getRequestSpecificRetryHandler(request, config); - assertEquals(1, retryHandler.getMaxRetriesOnNextServer()); - assertEquals(1, retryHandler.getMaxRetriesOnSameServer()); - - } - - @Test - public void choose() throws Exception { - RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config); - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class)); - RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory); - HttpRequest springRequest = mock(HttpRequest.class); - Request feignRequest = Request.create("GET", "http://foo", new HashMap>(), - new byte[]{}, StandardCharsets.UTF_8); - Client client = mock(Client.class); - FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo")); - Response response = Response.builder().status(200).headers(new HashMap>()).build(); - doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class)); - final Server server = new Server("foo", 80); - RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(new ILoadBalancer() { - @Override - public void addServers(List list) { - - } - - @Override - public Server chooseServer(Object o) { - return server; - } - - @Override - public void markServerDown(Server server) { - - } - - @Override - public List getServerList(boolean b) { - return null; - } - - @Override - public List getReachableServers() { - return null; - } - - @Override - public List getAllServers() { - return null; - } - }, config, inspector, loadBalancedRetryPolicyFactory, loadBalancedBackOffPolicyFactory); - ServiceInstance serviceInstance = feignLb.choose("foo"); - assertEquals("foo", serviceInstance.getHost()); - assertEquals(80, serviceInstance.getPort()); - - } - - @Test - public void retryListenerTest() throws Exception { - RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config); - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - IClientConfig config = mock(IClientConfig.class); - doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt()); - doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(true).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false)); - doReturn(defaultConnectTimeout).when(config).get(eq(CommonClientConfigKey.ConnectTimeout)); - doReturn(defaultReadTimeout).when(config).get(eq(CommonClientConfigKey.ReadTimeout)); - doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq("")); - doReturn(config).when(clientFactory).getClientConfig(eq("default")); - doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class)); - RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory); - HttpRequest springRequest = mock(HttpRequest.class); - Request feignRequest = Request.create("GET", "http://listener", new HashMap>(), - new byte[]{}, StandardCharsets.UTF_8); - Client client = mock(Client.class); - FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://listener")); - Response response = Response.builder().status(200).headers(new HashMap>()).build(); - doThrow(new IOException("boom")).doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class)); - MyBackOffPolicyFactory backOffPolicyFactory = new MyBackOffPolicyFactory(); - MyRetryListeners myRetryListeners = new MyRetryListeners(); - RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory, - backOffPolicyFactory, myRetryListeners); - FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null); - assertEquals(200, ribbonResponse.toResponse().status()); - verify(client, times(2)).execute(any(Request.class), any(Request.Options.class)); - assertEquals(1, backOffPolicyFactory.getCount()); - assertEquals(1, myRetryListeners.getOnError()); - } - - @Test(expected = TerminatedRetryException.class) - public void retryListenerTestNoRetry() throws Exception { - RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config); - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - IClientConfig config = mock(IClientConfig.class); - doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt()); - doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(true).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false)); - doReturn(defaultConnectTimeout).when(config).get(eq(CommonClientConfigKey.ConnectTimeout)); - doReturn(defaultReadTimeout).when(config).get(eq(CommonClientConfigKey.ReadTimeout)); - doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq("")); - doReturn(config).when(clientFactory).getClientConfig(eq("default")); - doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class)); - RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory); - HttpRequest springRequest = mock(HttpRequest.class); - Request feignRequest = Request.create("GET", "http://listener", new HashMap>(), - new byte[]{}, StandardCharsets.UTF_8); - Client client = mock(Client.class); - FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://listener")); - Response response = Response.builder().status(200).headers(new HashMap>()).build(); - MyBackOffPolicyFactory backOffPolicyFactory = new MyBackOffPolicyFactory(); - MyRetryListenersNotRetry myRetryListenersNotRetry = new MyRetryListenersNotRetry(); - RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory, - backOffPolicyFactory, myRetryListenersNotRetry); - FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null); - } - - @Test - public void retryWithDefaultConstructorTest() throws Exception { - RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config); - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - IClientConfig config = mock(IClientConfig.class); - doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt()); - doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(true).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false)); - doReturn(defaultConnectTimeout).when(config).get(eq(CommonClientConfigKey.ConnectTimeout)); - doReturn(defaultReadTimeout).when(config).get(eq(CommonClientConfigKey.ReadTimeout)); - doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq("")); - doReturn(config).when(clientFactory).getClientConfig(eq("default")); - doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class)); - RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory); - HttpRequest springRequest = mock(HttpRequest.class); - Request feignRequest = Request.create("GET", "http://listener", new HashMap>(), - new byte[]{}, StandardCharsets.UTF_8); - Client client = mock(Client.class); - FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://listener")); - Response response = Response.builder().status(200).headers(new HashMap>()).build(); - doThrow(new IOException("boom")).doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class)); - MyBackOffPolicyFactory backOffPolicyFactory = new MyBackOffPolicyFactory(); - RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory, - backOffPolicyFactory); - FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null); - assertEquals(200, ribbonResponse.toResponse().status()); - verify(client, times(2)).execute(any(Request.class), any(Request.Options.class)); - assertEquals(1, backOffPolicyFactory.getCount()); - } - - @Test - public void executeRetryFail() throws Exception { - RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config); - lbContext.setRetryHandler(new DefaultLoadBalancerRetryHandler(1, 0, true)); - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - IClientConfig config = mock(IClientConfig.class); - doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt()); - doReturn(0).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(true).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false)); - doReturn(defaultConnectTimeout).when(config).get(eq(CommonClientConfigKey.ConnectTimeout)); - doReturn(defaultReadTimeout).when(config).get(eq(CommonClientConfigKey.ReadTimeout)); - doReturn("404").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq("")); - doReturn(config).when(clientFactory).getClientConfig(eq("default")); - doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class)); - RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory); - HttpRequest springRequest = mock(HttpRequest.class); - Request feignRequest = Request.create("GET", "http://foo", new HashMap>(), - new byte[]{}, StandardCharsets.UTF_8); - Client client = mock(Client.class); - FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo")); - Response fourOFourResponse = Response.builder().status(404).headers(new HashMap>()) - .body(new Response.Body() { //set content into response - @Override - public Integer length() { - return "test".getBytes().length; - } - - @Override - public boolean isRepeatable() { - return true; - } - - @Override - public InputStream asInputStream() throws IOException { - return new ByteArrayInputStream("test".getBytes()); - } - - @Override - public Reader asReader() throws IOException { - return new InputStreamReader(asInputStream(), "UTF-8"); - } - - @Override - public void close() throws IOException { - } - }).build(); - doReturn(fourOFourResponse).when(client).execute(any(Request.class), any(Request.Options.class)); - MyBackOffPolicyFactory backOffPolicyFactory = new MyBackOffPolicyFactory(); - RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory, backOffPolicyFactory); - FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null); - verify(client, times(2)).execute(any(Request.class), any(Request.Options.class)); - assertEquals(1, backOffPolicyFactory.getCount()); - InputStream inputStream = ribbonResponse.toResponse().body().asInputStream(); - byte[] buf = new byte[100]; - int read = inputStream.read(buf); - Assert.assertThat(new String(buf, 0, read), is("test")); - } - - class MyBackOffPolicyFactory implements LoadBalancedBackOffPolicyFactory, BackOffPolicy { - - private int count = 0; - - @Override - public BackOffContext start(RetryContext retryContext) { - return null; - } - - @Override - public void backOff(BackOffContext backOffContext) throws BackOffInterruptedException { - count++; - } - - public int getCount() { - return count; - } - - @Override - public BackOffPolicy createBackOffPolicy(String service) { - return this; - } - } - - class MyRetryListeners implements LoadBalancedRetryListenerFactory { - - private int onError = 0; - - @Override - public RetryListener[] createRetryListeners(String service) { - return new RetryListener[] {new RetryListener() { - @Override - public boolean open(RetryContext context, RetryCallback callback) { - return true; - } - - @Override - public void close(RetryContext context, RetryCallback callback, Throwable throwable) { - - } - - @Override - public void onError(RetryContext context, RetryCallback callback, Throwable throwable) { - onError++; - } - }}; - } - - public int getOnError() { - return onError; - } - } - - class MyRetryListenersNotRetry implements LoadBalancedRetryListenerFactory { - - @Override - public RetryListener[] createRetryListeners(String service) { - return new RetryListener[] {new RetryListener() { - @Override - public boolean open(RetryContext context, RetryCallback callback) { - return false; - } - - @Override - public void close(RetryContext context, RetryCallback callback, Throwable throwable) { - - } - - @Override - public void onError(RetryContext context, RetryCallback callback, Throwable throwable) { - - } - }}; - } - } - -} \ No newline at end of file diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/RibbonResponseStatusCodeExceptionTest.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/RibbonResponseStatusCodeExceptionTest.java deleted file mode 100644 index 5dc7ac234..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/ribbon/RibbonResponseStatusCodeExceptionTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2013-2018 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.feign.ribbon; - -import feign.Request; -import feign.Response; - -import java.io.ByteArrayInputStream; -import java.net.URI; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.runners.MockitoJUnitRunner; -import org.springframework.util.StreamUtils; - -import static org.junit.Assert.assertEquals; - -/** - * @author Ryan Baxter - */ -@RunWith(MockitoJUnitRunner.class) -public class RibbonResponseStatusCodeExceptionTest { - - @Test - public void getResponse() throws Exception { - Map> headers = new HashMap>(); - List fooValues = new ArrayList(); - fooValues.add("bar"); - headers.put("foo", fooValues); - Request request = Request.create("GET", "http://service.com", - new HashMap>(), new byte[]{}, Charset.defaultCharset()); - byte[] body = "foo".getBytes(); - ByteArrayInputStream is = new ByteArrayInputStream(body); - Response response = Response.builder().status(200).reason("Success").request(request).body(is, body.length).headers(headers).build(); - RibbonResponseStatusCodeException ex = new RibbonResponseStatusCodeException("service", response, body, - new URI(request.url())); - assertEquals(200, ex.getResponse().status()); - assertEquals(request, ex.getResponse().request()); - assertEquals("Success", ex.getResponse().reason()); - assertEquals("foo", StreamUtils.copyToString(ex.getResponse().body().asInputStream(), Charset.defaultCharset())); - } -} \ No newline at end of file diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/FeignHttpClientPropertiesTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/FeignHttpClientPropertiesTests.java deleted file mode 100644 index 6431c6a49..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/FeignHttpClientPropertiesTests.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * - * * 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. - * - */ - -package org.springframework.cloud.netflix.feign.support; - -import org.junit.After; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.springframework.boot.test.util.EnvironmentTestUtils.addEnvironment; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@DirtiesContext -public class FeignHttpClientPropertiesTests { - - private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - - @After - public void clear() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - public void testDefaults() { - setupContext(); - assertEquals(FeignHttpClientProperties.DEFAULT_CONNECTION_TIMEOUT, getProperties().getConnectionTimeout()); - assertEquals(FeignHttpClientProperties.DEFAULT_MAX_CONNECTIONS, getProperties().getMaxConnections()); - assertEquals(FeignHttpClientProperties.DEFAULT_MAX_CONNECTIONS_PER_ROUTE, getProperties().getMaxConnectionsPerRoute()); - assertEquals(FeignHttpClientProperties.DEFAULT_TIME_TO_LIVE, getProperties().getTimeToLive()); - assertEquals(FeignHttpClientProperties.DEFAULT_DISABLE_SSL_VALIDATION, getProperties().isDisableSslValidation()); - assertEquals(FeignHttpClientProperties.DEFAULT_FOLLOW_REDIRECTS, getProperties().isFollowRedirects()); - } - - @Test - public void testCustomization() { - addEnvironment(this.context, "feign.httpclient.maxConnections=2", - "feign.httpclient.connectionTimeout=2", - "feign.httpclient.maxConnectionsPerRoute=2", - "feign.httpclient.timeToLive=2", - "feign.httpclient.disableSslValidation=true", - "feign.httpclient.followRedirects=false"); - setupContext(); - assertEquals(2, getProperties().getMaxConnections()); - assertEquals(2, getProperties().getConnectionTimeout()); - assertEquals(2, getProperties().getMaxConnectionsPerRoute()); - assertEquals(2L, getProperties().getTimeToLive()); - assertTrue(getProperties().isDisableSslValidation()); - assertFalse(getProperties().isFollowRedirects()); - } - - private void setupContext() { - this.context.register(PropertyPlaceholderAutoConfiguration.class, TestConfiguration.class); - this.context.refresh(); - } - - private FeignHttpClientProperties getProperties() { - return this.context.getBean(FeignHttpClientProperties.class); - } - - @Configuration - @EnableConfigurationProperties - protected static class TestConfiguration { - @Bean - FeignHttpClientProperties zuulProperties() { - return new FeignHttpClientProperties() ; - } - } -} \ No newline at end of file diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringEncoderTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringEncoderTests.java deleted file mode 100644 index 70af122d1..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringEncoderTests.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * 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.feign.support; - -import java.io.IOException; -import java.lang.reflect.Type; -import java.nio.charset.Charset; -import java.util.Collection; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentMatcher; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.cloud.netflix.feign.FeignContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpInputMessage; -import org.springframework.http.HttpOutputMessage; -import org.springframework.http.MediaType; -import org.springframework.http.converter.AbstractGenericHttpMessageConverter; -import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.http.converter.HttpMessageNotReadableException; -import org.springframework.http.converter.HttpMessageNotWritableException; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RestController; - -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertThat; - -import feign.RequestTemplate; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = SpringEncoderTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = { - "spring.application.name=springencodertest", "spring.jmx.enabled=false" }) -@DirtiesContext -public class SpringEncoderTests { - - @Autowired - private FeignContext context; - - @Autowired - @Qualifier("myHttpMessageConverter") - private HttpMessageConverter myConverter; - - @Test - public void testCustomHttpMessageConverter() { - SpringEncoder encoder = this.context.getInstance("foo", SpringEncoder.class); - assertThat(encoder, is(notNullValue())); - RequestTemplate request = new RequestTemplate(); - - encoder.encode("hi", MyType.class, request); - - Collection contentTypeHeader = request.headers().get("Content-Type"); - assertThat("missing content type header", contentTypeHeader, is(notNullValue())); - assertThat("missing content type header", contentTypeHeader.isEmpty(), is(false)); - - String header = contentTypeHeader.iterator().next(); - assertThat("content type header is wrong", header, is("application/mytype")); - - assertThat("request charset is null", request.charset(), is(notNullValue())); - assertThat("request charset is wrong", request.charset(), is(Charset.forName("UTF-8"))); - } - - @Test - public void testBinaryData() { - SpringEncoder encoder = this.context.getInstance("foo", SpringEncoder.class); - assertThat(encoder, is(notNullValue())); - RequestTemplate request = new RequestTemplate(); - - encoder.encode("hi".getBytes(), null, request); - - assertThat("request charset is not null", request.charset(), is(nullValue())); - } - - class MediaTypeMatcher implements ArgumentMatcher { - - private MediaType mediaType; - - public MediaTypeMatcher(String type, String subtype) { - this.mediaType = new MediaType(type, subtype); - } - - @Override - public boolean matches(MediaType argument) { - return this.mediaType.equals(argument); - } - - @Override - public String toString() { - final StringBuffer sb = new StringBuffer("MediaTypeMatcher{"); - sb.append("mediaType=").append(this.mediaType); - sb.append('}'); - return sb.toString(); - } - } - - protected static class MyType { - private String value; - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - } - - protected interface TestClient { - - } - - @Configuration - @EnableAutoConfiguration - @RestController - protected static class Application implements TestClient { - - @Bean - HttpMessageConverter myHttpMessageConverter() { - return new MyHttpMessageConverter(); - } - - private static class MyHttpMessageConverter - extends AbstractGenericHttpMessageConverter { - - public MyHttpMessageConverter() { - super(new MediaType("application", "mytype")); - } - - @Override - protected boolean supports(Class clazz) { - return false; - } - - @Override - public boolean canRead(Class clazz, MediaType mediaType) { - return true; - } - - @Override - public boolean canWrite(Class clazz, MediaType mediaType) { - if (clazz == String.class) { - return true; - } - return false; - } - - @Override - protected void writeInternal(Object o, Type type, - HttpOutputMessage outputMessage) - throws IOException, HttpMessageNotWritableException { - - } - - @Override - protected Object readInternal(Class clazz, HttpInputMessage inputMessage) - throws IOException, HttpMessageNotReadableException { - return null; - } - - @Override - public Object read(Type type, Class contextClass, - HttpInputMessage inputMessage) - throws IOException, HttpMessageNotReadableException { - return null; - } - } - } - -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringMvcContractTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringMvcContractTests.java deleted file mode 100644 index 325707818..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringMvcContractTests.java +++ /dev/null @@ -1,594 +0,0 @@ -/* - * 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. - */ - -package org.springframework.cloud.netflix.feign.support; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.util.MultiValueMap; -import org.springframework.util.ReflectionUtils; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; - -import com.fasterxml.jackson.annotation.JsonAutoDetect; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assume.assumeTrue; - -import feign.MethodMetadata; - -/** - * @author chadjaros - */ -public class SpringMvcContractTests { - private static final Class EXECUTABLE_TYPE; - - static { - Class executableType; - try { - executableType = Class.forName("java.lang.reflect.Executable"); - } - catch (ClassNotFoundException ex) { - executableType = null; - } - EXECUTABLE_TYPE = executableType; - } - - private SpringMvcContract contract; - - @Before - public void setup() { - this.contract = new SpringMvcContract(); - } - - @Test - public void testProcessAnnotationOnMethod_Simple() throws Exception { - Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest", - String.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("/test/{id}", data.template().url()); - assertEquals("GET", data.template().method()); - assertEquals(MediaType.APPLICATION_JSON_VALUE, - data.template().headers().get("Accept").iterator().next()); - } - - @Test - public void testProcessAnnotations_Simple() throws Exception { - Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest", - String.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("/test/{id}", data.template().url()); - assertEquals("GET", data.template().method()); - assertEquals(MediaType.APPLICATION_JSON_VALUE, - data.template().headers().get("Accept").iterator().next()); - - assertEquals("id", data.indexToName().get(0).iterator().next()); - } - - @Test - public void testProcessAnnotations_SimpleGetMapping() throws Exception { - Method method = TestTemplate_Simple.class.getDeclaredMethod("getMappingTest", - String.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("/test/{id}", data.template().url()); - assertEquals("GET", data.template().method()); - assertEquals(MediaType.APPLICATION_JSON_VALUE, - data.template().headers().get("Accept").iterator().next()); - - assertEquals("id", data.indexToName().get(0).iterator().next()); - } - - @Test - public void testProcessAnnotations_Class_AnnotationsGetSpecificTest() - throws Exception { - Method method = TestTemplate_Class_Annotations.class - .getDeclaredMethod("getSpecificTest", String.class, String.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("/prepend/{classId}/test/{testId}", data.template().url()); - assertEquals("GET", data.template().method()); - - assertEquals("classId", data.indexToName().get(0).iterator().next()); - assertEquals("testId", data.indexToName().get(1).iterator().next()); - } - - @Test - public void testProcessAnnotations_Class_AnnotationsGetAllTests() throws Exception { - Method method = TestTemplate_Class_Annotations.class - .getDeclaredMethod("getAllTests", String.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("/prepend/{classId}", data.template().url()); - assertEquals("GET", data.template().method()); - - assertEquals("classId", data.indexToName().get(0).iterator().next()); - } - - @Test - public void testProcessAnnotations_ExtendedInterface() throws Exception { - Method extendedMethod = TestTemplate_Extended.class.getMethod("getAllTests", - String.class); - MethodMetadata extendedData = this.contract.parseAndValidateMetadata( - extendedMethod.getDeclaringClass(), extendedMethod); - - Method method = TestTemplate_Class_Annotations.class - .getDeclaredMethod("getAllTests", String.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals(extendedData.template().url(), data.template().url()); - assertEquals(extendedData.template().method(), data.template().method()); - - assertEquals(data.indexToName().get(0).iterator().next(), - data.indexToName().get(0).iterator().next()); - } - - @Test - public void testProcessAnnotations_SimplePost() throws Exception { - Method method = TestTemplate_Simple.class.getDeclaredMethod("postTest", - TestObject.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("", data.template().url()); - assertEquals("POST", data.template().method()); - assertEquals(MediaType.APPLICATION_JSON_VALUE, - data.template().headers().get("Accept").iterator().next()); - - } - - @Test - public void testProcessAnnotations_SimplePostMapping() throws Exception { - Method method = TestTemplate_Simple.class.getDeclaredMethod("postMappingTest", - TestObject.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("", data.template().url()); - assertEquals("POST", data.template().method()); - assertEquals(MediaType.APPLICATION_JSON_VALUE, - data.template().headers().get("Accept").iterator().next()); - - } - - @Test - public void testProcessAnnotationsOnMethod_Advanced() throws Exception { - Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest", - String.class, String.class, Integer.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("/advanced/test/{id}", data.template().url()); - assertEquals("PUT", data.template().method()); - assertEquals(MediaType.APPLICATION_JSON_VALUE, - data.template().headers().get("Accept").iterator().next()); - } - - @Test - public void testProcessAnnotationsOnMethod_Advanced_UnknownAnnotation() - throws Exception { - Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest", - String.class, String.class, Integer.class); - this.contract.parseAndValidateMetadata(method.getDeclaringClass(), method); - - // Don't throw an exception and this passes - } - - @Test - public void testProcessAnnotations_Advanced() throws Exception { - Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest", - String.class, String.class, Integer.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("/advanced/test/{id}", data.template().url()); - assertEquals("PUT", data.template().method()); - assertEquals(MediaType.APPLICATION_JSON_VALUE, - data.template().headers().get("Accept").iterator().next()); - - assertEquals("Authorization", data.indexToName().get(0).iterator().next()); - assertEquals("id", data.indexToName().get(1).iterator().next()); - assertEquals("amount", data.indexToName().get(2).iterator().next()); - assertNotNull(data.indexToExpander().get(2)); - - assertEquals("{Authorization}", - data.template().headers().get("Authorization").iterator().next()); - assertEquals("{amount}", - data.template().queries().get("amount").iterator().next()); - } - - @Test - public void testProcessAnnotations_Aliased() throws Exception { - Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest2", - String.class, Integer.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("/advanced/test2", data.template().url()); - assertEquals("PUT", data.template().method()); - assertEquals(MediaType.APPLICATION_JSON_VALUE, - data.template().headers().get("Accept").iterator().next()); - - assertEquals("Authorization", data.indexToName().get(0).iterator().next()); - assertEquals("amount", data.indexToName().get(1).iterator().next()); - - assertEquals("{Authorization}", - data.template().headers().get("Authorization").iterator().next()); - assertEquals("{amount}", - data.template().queries().get("amount").iterator().next()); - } - - @Test - public void testProcessAnnotations_Advanced2() throws Exception { - Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest"); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("/advanced", data.template().url()); - assertEquals("GET", data.template().method()); - assertEquals(MediaType.APPLICATION_JSON_VALUE, - data.template().headers().get("Accept").iterator().next()); - } - - @Test - public void testProcessAnnotations_Advanced3() throws Exception { - Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest"); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("", data.template().url()); - assertEquals("GET", data.template().method()); - assertEquals(MediaType.APPLICATION_JSON_VALUE, - data.template().headers().get("Accept").iterator().next()); - } - - @Test - public void testProcessAnnotations_ListParams() throws Exception { - Method method = TestTemplate_ListParams.class.getDeclaredMethod("getTest", - List.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("/test", data.template().url()); - assertEquals("GET", data.template().method()); - assertEquals("[{id}]", data.template().queries().get("id").toString()); - assertNotNull(data.indexToExpander().get(0)); - } - - @Test - public void testProcessAnnotations_ListParamsWithoutName() throws Exception { - Method method = TestTemplate_ListParamsWithoutName.class.getDeclaredMethod("getTest", - List.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("/test", data.template().url()); - assertEquals("GET", data.template().method()); - assertEquals("[{id}]", data.template().queries().get("id").toString()); - assertNotNull(data.indexToExpander().get(0)); - } - - @Test - public void testProcessAnnotations_MapParams() throws Exception { - Method method = TestTemplate_MapParams.class.getDeclaredMethod("getTest", - Map.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("/test", data.template().url()); - assertEquals("GET", data.template().method()); - assertNotNull(data.queryMapIndex()); - assertEquals(0, data.queryMapIndex().intValue()); - } - - @Test - public void testProcessHeaders() throws Exception { - Method method = TestTemplate_Headers.class.getDeclaredMethod("getTest", - String.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("/test/{id}", data.template().url()); - assertEquals("GET", data.template().method()); - assertEquals("bar", data.template().headers().get("X-Foo").iterator().next()); - } - - @Test - public void testProcessHeadersWithoutValues() throws Exception { - Method method = TestTemplate_HeadersWithoutValues.class.getDeclaredMethod("getTest", - String.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("/test/{id}", data.template().url()); - assertEquals("GET", data.template().method()); - assertEquals(true, data.template().headers().isEmpty()); - } - - @Test - public void testProcessAnnotations_Fallback() throws Exception { - Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTestFallback", - String.class, String.class, Integer.class); - - assumeTrue("does not have java 8 parameter names", hasJava8ParameterNames(method)); - - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("/advanced/testfallback/{id}", data.template().url()); - assertEquals("PUT", data.template().method()); - assertEquals(MediaType.APPLICATION_JSON_VALUE, - data.template().headers().get("Accept").iterator().next()); - - assertEquals("Authorization", data.indexToName().get(0).iterator().next()); - assertEquals("id", data.indexToName().get(1).iterator().next()); - assertEquals("amount", data.indexToName().get(2).iterator().next()); - - assertEquals("{Authorization}", - data.template().headers().get("Authorization").iterator().next()); - assertEquals("{amount}", - data.template().queries().get("amount").iterator().next()); - } - - /** - * For abstract (e.g. interface) methods, only Java 8 Parameter names (compiler arg - * -parameters) can supply parameter names; bytecode-based strategies use local - * variable declarations, of which there are none for abstract methods. - * @param m - * @return whether a parameter name was found - * @throws IllegalArgumentException if method has no parameters - */ - private static boolean hasJava8ParameterNames(Method m) { - org.springframework.util.Assert.isTrue(m.getParameterTypes().length > 0, - "method has no parameters"); - if (EXECUTABLE_TYPE != null) { - Method getParameters = ReflectionUtils.findMethod(EXECUTABLE_TYPE, - "getParameters"); - try { - Object[] parameters = (Object[]) getParameters.invoke(m); - Method isNamePresent = ReflectionUtils - .findMethod(parameters[0].getClass(), "isNamePresent"); - return Boolean.TRUE.equals(isNamePresent.invoke(parameters[0])); - } - catch (IllegalAccessException | IllegalArgumentException - | InvocationTargetException ex) { - } - } - return false; - } - - @Test - public void testProcessHeaderMap() throws Exception { - Method method = TestTemplate_HeaderMap.class.getDeclaredMethod("headerMap", - MultiValueMap.class, String.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("/headerMap", data.template().url()); - assertEquals("GET", data.template().method()); - assertEquals(0, data.headerMapIndex().intValue()); - Map> headers = data.template().headers(); - assertEquals("{aHeader}", headers.get("aHeader").iterator().next()); - } - - @Test(expected = IllegalStateException.class) - public void testProcessHeaderMapMoreThanOnce() throws Exception { - Method method = TestTemplate_HeaderMap.class.getDeclaredMethod( - "headerMapMoreThanOnce", MultiValueMap.class, MultiValueMap.class); - this.contract.parseAndValidateMetadata(method.getDeclaringClass(), method); - } - - @Test - public void testProcessQueryMap() throws Exception { - Method method = TestTemplate_QueryMap.class.getDeclaredMethod("queryMap", - MultiValueMap.class, String.class); - MethodMetadata data = this.contract - .parseAndValidateMetadata(method.getDeclaringClass(), method); - - assertEquals("/queryMap", data.template().url()); - assertEquals("GET", data.template().method()); - assertEquals(0, data.queryMapIndex().intValue()); - Map> params = data.template().queries(); - assertEquals("{aParam}", params.get("aParam").iterator().next()); - } - - @Test(expected = IllegalStateException.class) - public void testProcessQueryMapMoreThanOnce() throws Exception { - Method method = TestTemplate_QueryMap.class.getDeclaredMethod( - "queryMapMoreThanOnce", MultiValueMap.class, MultiValueMap.class); - this.contract.parseAndValidateMetadata(method.getDeclaringClass(), method); - } - - public interface TestTemplate_Simple { - @RequestMapping(value = "/test/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) - ResponseEntity getTest(@PathVariable("id") String id); - - @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) - TestObject getTest(); - - @GetMapping(value = "/test/{id}", produces = MediaType.APPLICATION_JSON_VALUE) - ResponseEntity getMappingTest(@PathVariable("id") String id); - - @RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) - TestObject postTest(@RequestBody TestObject object); - - @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE) - TestObject postMappingTest(@RequestBody TestObject object); - } - - @RequestMapping("/prepend/{classId}") - public interface TestTemplate_Class_Annotations { - @RequestMapping(value = "/test/{testId}", method = RequestMethod.GET) - TestObject getSpecificTest(@PathVariable("classId") String classId, - @PathVariable("testId") String testId); - - @RequestMapping(method = RequestMethod.GET) - TestObject getAllTests(@PathVariable("classId") String classId); - } - - public interface TestTemplate_Extended extends TestTemplate_Class_Annotations { - - } - - public interface TestTemplate_Headers { - @RequestMapping(value = "/test/{id}", method = RequestMethod.GET, headers = "X-Foo=bar") - ResponseEntity getTest(@PathVariable("id") String id); - } - - public interface TestTemplate_HeadersWithoutValues { - @RequestMapping(value = "/test/{id}", method = RequestMethod.GET, headers = { "X-Foo", "!X-Bar", "X-Baz!=fooBar" }) - ResponseEntity getTest(@PathVariable("id") String id); - } - - public interface TestTemplate_ListParams { - @RequestMapping(value = "/test", method = RequestMethod.GET) - ResponseEntity getTest(@RequestParam("id") List id); - } - - public interface TestTemplate_ListParamsWithoutName { - @RequestMapping(value = "/test", method = RequestMethod.GET) - ResponseEntity getTest(@RequestParam List id); - } - - public interface TestTemplate_MapParams { - @RequestMapping(value = "/test", method = RequestMethod.GET) - ResponseEntity getTest(@RequestParam Map params); - } - - public interface TestTemplate_HeaderMap { - @RequestMapping(path = "/headerMap") - String headerMap( - @RequestHeader MultiValueMap headerMap, - @RequestHeader(name = "aHeader") String aHeader); - - @RequestMapping(path = "/headerMapMoreThanOnce") - String headerMapMoreThanOnce( - @RequestHeader MultiValueMap headerMap1, - @RequestHeader MultiValueMap headerMap2); - } - - public interface TestTemplate_QueryMap { - @RequestMapping(path = "/queryMap") - String queryMap( - @RequestParam MultiValueMap queryMap, - @RequestParam(name = "aParam") String aParam); - - @RequestMapping(path = "/queryMapMoreThanOnce") - String queryMapMoreThanOnce( - @RequestParam MultiValueMap queryMap1, - @RequestParam MultiValueMap queryMap2); - } - - @JsonAutoDetect - @RequestMapping("/advanced") - public interface TestTemplate_Advanced { - - @ExceptionHandler - @RequestMapping(path = "/test/{id}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE) - ResponseEntity getTest(@RequestHeader("Authorization") String auth, - @PathVariable("id") String id, @RequestParam("amount") Integer amount); - - @RequestMapping(path = "/test2", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE) - ResponseEntity getTest2( - @RequestHeader(name = "Authorization") String auth, - @RequestParam(name = "amount") Integer amount); - - @ExceptionHandler - @RequestMapping(path = "/testfallback/{id}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE) - ResponseEntity getTestFallback(@RequestHeader String Authorization, - @PathVariable String id, @RequestParam Integer amount); - - @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) - TestObject getTest(); - } - - @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE) - public class TestObject { - - public String something; - public Double number; - - public TestObject() { - } - - public TestObject(String something, Double number) { - this.something = something; - this.number = number; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - TestObject that = (TestObject) o; - - if (this.number != null ? !this.number.equals(that.number) - : that.number != null) { - return false; - } - if (this.something != null ? !this.something.equals(that.something) - : that.something != null) { - return false; - } - - return true; - } - - @Override - public int hashCode() { - int result = (this.something != null ? this.something.hashCode() : 0); - result = 31 * result + (this.number != null ? this.number.hashCode() : 0); - return result; - } - - @Override - public String toString() { - return new StringBuilder("TestObject{") - .append("something='").append(something).append("', ") - .append("number=").append(number) - .append("}").toString(); - } - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/testclients/TestClient.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/testclients/TestClient.java deleted file mode 100644 index 6788d657e..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/testclients/TestClient.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * - * * 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. - * - */ -package org.springframework.cloud.netflix.feign.testclients; - -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -/** - * @author Ryan Baxter - */ -@FeignClient(name = "localapp") -public interface TestClient { - @RequestMapping(method = RequestMethod.GET, value = "/hello") - String getHello(); -} - diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientNotPrimaryTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientNotPrimaryTests.java deleted file mode 100644 index 5f11411b2..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientNotPrimaryTests.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * 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.feign.valid; - -import java.util.List; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; - -import feign.Logger; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertNull; - -/** - * @author Spencer Gibb - * @author Jakub Narloch - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = FeignClientNotPrimaryTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = { - "spring.application.name=feignclientnotprimarytest", - "logging.level.org.springframework.cloud.netflix.feign.valid=DEBUG", - "feign.httpclient.enabled=false", "feign.okhttp.enabled=false" }) -@DirtiesContext -public class FeignClientNotPrimaryTests { - - public static final String HELLO_WORLD_1 = "hello world 1"; - public static final String OI_TERRA_2 = "oi terra 2"; - public static final String MYHEADER1 = "myheader1"; - public static final String MYHEADER2 = "myheader2"; - - @Value("${local.server.port}") - private int port = 0; - - @Autowired - private TestClient testClient; - - @Autowired - private List testClients; - - @FeignClient(name = "localapp", primary = false) - protected interface TestClient { - @RequestMapping(method = RequestMethod.GET, path = "/hello") - Hello getHello(); - - } - - @Configuration - @EnableAutoConfiguration - @RestController - @EnableFeignClients(clients = { TestClient.class} , - defaultConfiguration = TestDefaultFeignConfig.class) - @RibbonClient(name = "localapp", configuration = LocalRibbonClientConfiguration.class) - protected static class Application { - - @Bean - @Primary - public PrimaryTestClient primaryTestClient() { - return new PrimaryTestClient(); - } - - @RequestMapping(method = RequestMethod.GET, path = "/hello") - public Hello getHello() { - return new Hello(HELLO_WORLD_1); - } - - } - - @Test - public void testClientType() { - assertThat(this.testClient).as("testClient was of wrong type").isInstanceOf(PrimaryTestClient.class); - } - - @Test - public void testClientCount() { - assertThat(this.testClients).as("testClients was wrong").hasSize(2); - } - - @Test - public void testSimpleType() { - Hello hello = this.testClient.getHello(); - assertNull("hello was null", hello); - } - - protected static class PrimaryTestClient implements TestClient { - @Override - public Hello getHello() { - return null; - } - } - - public static class Hello { - private String message; - - public Hello() {} - - public Hello(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - } - - @Configuration - public static class TestDefaultFeignConfig { - @Bean - Logger.Level feignLoggerLevel() { - return Logger.Level.FULL; - } - } - - // Load balancer with fixed server list for "local" pointing to localhost - @Configuration - public static class LocalRibbonClientConfiguration { - - @Value("${local.server.port}") - private int port = 0; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientTests.java deleted file mode 100644 index 039b91c0f..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientTests.java +++ /dev/null @@ -1,802 +0,0 @@ -/* - * 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.feign.valid; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Locale; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.cloud.netflix.feign.FeignFormatterRegistrar; -import org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient; -import org.springframework.cloud.netflix.feign.support.FallbackCommand; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.format.Formatter; -import org.springframework.format.FormatterRegistry; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import com.netflix.hystrix.HystrixCommand; -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - -import feign.Client; -import feign.Feign; -import feign.Logger; -import feign.RequestInterceptor; -import feign.RequestTemplate; -import feign.Target; -import feign.hystrix.FallbackFactory; -import feign.hystrix.SetterFactory; -import rx.Observable; -import rx.Single; - -/** - * @author Spencer Gibb - * @author Jakub Narloch - * @author Erik Kringen - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = FeignClientTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = { - "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"}) -@DirtiesContext -public class FeignClientTests { - - public static final String HELLO_WORLD_1 = "hello world 1"; - public static final String OI_TERRA_2 = "oi terra 2"; - public static final String MYHEADER1 = "myheader1"; - public static final String MYHEADER2 = "myheader2"; - - @Value("${local.server.port}") - private int port = 0; - - @Autowired - private TestClient testClient; - - @Autowired - private TestClientServiceId testClientServiceId; - - @Autowired - private DecodingTestClient decodingTestClient; - - @Autowired - private Client feignClient; - - @Autowired - HystrixClient hystrixClient; - - @Autowired - private HystrixClientWithFallBackFactory hystrixClientWithFallBackFactory; - - @Autowired - @Qualifier("localapp3FeignClient") - HystrixClient namedHystrixClient; - - @Autowired - HystrixSetterFactoryClient hystrixSetterFactoryClient; - - protected enum Arg { - A, B; - - @Override - public String toString() { - return name().toLowerCase(Locale.ENGLISH); - } - } - - protected static class OtherArg { - public final String value; - - public OtherArg(String value) { - this.value = value; - } - - @Override - public String toString() { - return value; - } - } - - @FeignClient(name = "localapp", configuration = TestClientConfig.class) - protected interface TestClient { - @RequestMapping(method = RequestMethod.GET, path = "/hello") - Hello getHello(); - - @RequestMapping(method = RequestMethod.GET, path = "/hello") - Optional getOptionalHello(); - - @RequestMapping(method = RequestMethod.GET, path = "${feignClient.methodLevelRequestMappingPath}") - Hello getHelloUsingPropertyPlaceHolder(); - - @RequestMapping(method = RequestMethod.GET, path = "/hello") - Single getHelloSingle(); - - @RequestMapping(method = RequestMethod.GET, path = "/hellos") - List getHellos(); - - @RequestMapping(method = RequestMethod.GET, path = "/hellostrings") - List getHelloStrings(); - - @RequestMapping(method = RequestMethod.GET, path = "/helloheaders") - List getHelloHeaders(); - - @RequestMapping(method = RequestMethod.GET, path = "/helloheadersplaceholders", headers = "myPlaceholderHeader=${feignClient.myPlaceholderHeader}") - String getHelloHeadersPlaceholders(); - - @RequestMapping(method = RequestMethod.GET, path = "/helloparams") - List getParams(@RequestParam("params") List params); - - @RequestMapping(method = RequestMethod.GET, path = "/hellos") - HystrixCommand> getHellosHystrix(); - - @RequestMapping(method = RequestMethod.GET, path = "/noContent") - ResponseEntity noContent(); - - @RequestMapping(method = RequestMethod.HEAD, path = "/head") - ResponseEntity head(); - - @RequestMapping(method = RequestMethod.GET, path = "/hello") - HttpEntity getHelloEntity(); - - @RequestMapping(method = RequestMethod.POST, consumes = "application/vnd.io.spring.cloud.test.v1+json", produces = "application/vnd.io.spring.cloud.test.v1+json", path = "/complex") - String moreComplexContentType(String body); - - @RequestMapping(method = RequestMethod.GET, path = "/tostring") - String getToString(@RequestParam("arg") Arg arg); - - @RequestMapping(method = RequestMethod.GET, path = "/tostring2") - String getToString(@RequestParam("arg") OtherArg arg); - - @RequestMapping(method = RequestMethod.GET, path = "/tostringcollection") - Collection getToString(@RequestParam("arg") Collection args); - } - - public static class TestClientConfig { - - @Bean - public RequestInterceptor interceptor1() { - return new RequestInterceptor() { - @Override - public void apply(RequestTemplate template) { - template.header(MYHEADER1, "myheader1value"); - } - }; - } - - @Bean - public RequestInterceptor interceptor2() { - return new RequestInterceptor() { - @Override - public void apply(RequestTemplate template) { - template.header(MYHEADER2, "myheader2value"); - } - }; - } - } - - @FeignClient(name = "localapp1") - protected interface TestClientServiceId { - @RequestMapping(method = RequestMethod.GET, path = "/hello") - Hello getHello(); - } - - @FeignClient(name = "localapp2", decode404 = true) - protected interface DecodingTestClient { - @RequestMapping(method = RequestMethod.GET, path = "/notFound") - ResponseEntity notFound(); - - @RequestMapping(method = RequestMethod.GET, path = "/notFound") - Optional optional(); - } - - @FeignClient(name = "localapp3", fallback = HystrixClientFallback.class) - protected interface HystrixClient { - @RequestMapping(method = RequestMethod.GET, path = "/fail") - Single failSingle(); - - @RequestMapping(method = RequestMethod.GET, path = "/fail") - Hello fail(); - - @RequestMapping(method = RequestMethod.GET, path = "/fail") - HystrixCommand failCommand(); - - @RequestMapping(method = RequestMethod.GET, path = "/fail") - Observable failObservable(); - - @RequestMapping(method = RequestMethod.GET, path = "/fail") - Future failFuture(); - } - - @FeignClient(name = "localapp4", fallbackFactory = HystrixClientFallbackFactory.class) - protected interface HystrixClientWithFallBackFactory { - - @RequestMapping(method = RequestMethod.GET, path = "/fail") - Hello fail(); - } - - static class HystrixClientFallbackFactory implements FallbackFactory { - - @Override - public HystrixClientWithFallBackFactory create(final Throwable cause) { - return new HystrixClientWithFallBackFactory() { - @Override - public Hello fail() { - assertNotNull("Cause was null", cause); - return new Hello("Hello from the fallback side: " + cause.getMessage()); - } - }; - } - } - - static class HystrixClientFallback implements HystrixClient { - @Override - public Hello fail() { - return new Hello("fallback"); - } - - @Override - public Single failSingle() { - return Single.just(new Hello("fallbacksingle")); - } - - @Override - public HystrixCommand failCommand() { - return new FallbackCommand<>(new Hello("fallbackcommand")); - } - - @Override - public Observable failObservable() { - return Observable.just(new Hello("fallbackobservable")); - } - - @Override - public Future failFuture() { - return new FallbackCommand<>(new Hello("fallbackfuture")).queue(); - } - } - - @FeignClient(name = "localapp5", configuration = TestHystrixSetterFactoryClientConfig.class) - protected interface HystrixSetterFactoryClient { - @RequestMapping(method = RequestMethod.GET, path = "/hellos") - HystrixCommand> getHellosHystrix(); - } - - public static class TestHystrixSetterFactoryClientConfig { - public static final String SETTER_PREFIX = "SETTER-"; - @Bean - public SetterFactory commandKeyIsRequestLineSetterFactory() { - return new SetterFactory() { - @Override public HystrixCommand.Setter create(Target target, - Method method) { - String groupKey = SETTER_PREFIX + target.name(); - RequestMapping requestMapping = method - .getAnnotation(RequestMapping.class); - String commandKey = - SETTER_PREFIX + requestMapping.method()[0] + " " + requestMapping - .path()[0]; - return HystrixCommand.Setter - .withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey)) - .andCommandKey(HystrixCommandKey.Factory.asKey(commandKey)); - } - }; - } - } - - @Configuration - @EnableAutoConfiguration - @RestController - @EnableFeignClients(clients = { TestClientServiceId.class, TestClient.class, - DecodingTestClient.class, HystrixClient.class, HystrixClientWithFallBackFactory.class, - HystrixSetterFactoryClient.class}, - defaultConfiguration = TestDefaultFeignConfig.class) - @RibbonClients({ - @RibbonClient(name = "localapp", configuration = LocalRibbonClientConfiguration.class), - @RibbonClient(name = "localapp1", configuration = LocalRibbonClientConfiguration.class), - @RibbonClient(name = "localapp2", configuration = LocalRibbonClientConfiguration.class), - @RibbonClient(name = "localapp3", configuration = LocalRibbonClientConfiguration.class), - @RibbonClient(name = "localapp4", configuration = LocalRibbonClientConfiguration.class), - @RibbonClient(name = "localapp5", configuration = LocalRibbonClientConfiguration.class) - }) - protected static class Application { - - // needs to be in parent context to test multiple HystrixClient beans - @Bean - public HystrixClientFallback hystrixClientFallback() { - return new HystrixClientFallback(); - } - - @Bean - public HystrixClientFallbackFactory hystrixClientFallbackFactory() { - return new HystrixClientFallbackFactory(); - } - - @Bean - FeignFormatterRegistrar feignFormatterRegistrar() { - return new FeignFormatterRegistrar() { - - @Override - public void registerFormatters(FormatterRegistry registry) { - registry.addFormatter(new Formatter() { - - @Override - public String print(OtherArg object, Locale locale) { - if("foo".equals(object.value)) { - return "bar"; - } - return object.value; - } - - @Override - public OtherArg parse(String text, Locale locale) - throws ParseException { - return new OtherArg(text); - } - }); - } - }; - } - - @RequestMapping(method = RequestMethod.GET, path = "/hello") - public Hello getHello() { - return new Hello(HELLO_WORLD_1); - } - - @RequestMapping(method = RequestMethod.GET, path = "/hello2") - public Hello getHello2() { - return new Hello(OI_TERRA_2); - } - - @RequestMapping(method = RequestMethod.GET, path = "/hellos") - public List getHellos() { - ArrayList hellos = getHelloList(); - return hellos; - } - - @RequestMapping(method = RequestMethod.GET, path = "/hellostrings") - public List getHelloStrings() { - ArrayList hellos = new ArrayList<>(); - hellos.add(HELLO_WORLD_1); - hellos.add(OI_TERRA_2); - return hellos; - } - - @RequestMapping(method = RequestMethod.GET, path = "/helloheaders") - public List getHelloHeaders(@RequestHeader(MYHEADER1) String myheader1, - @RequestHeader(MYHEADER2) String myheader2) { - ArrayList headers = new ArrayList<>(); - headers.add(myheader1); - headers.add(myheader2); - return headers; - } - - @RequestMapping(method = RequestMethod.GET, path = "/helloheadersplaceholders") - public String getHelloHeadersPlaceholders( - @RequestHeader("myPlaceholderHeader") String myPlaceholderHeader) { - return myPlaceholderHeader; - } - - @RequestMapping(method = RequestMethod.GET, path = "/helloparams") - public List getParams(@RequestParam("params") List params) { - return params; - } - - @RequestMapping(method = RequestMethod.GET, path = "/noContent") - ResponseEntity noContent() { - return ResponseEntity.noContent().build(); - } - - @RequestMapping(method = RequestMethod.HEAD, path = "/head") - ResponseEntity head() { - return ResponseEntity.ok().build(); - } - - @RequestMapping(method = RequestMethod.GET, path = "/fail") - String fail() { - throw new RuntimeException("always fails"); - } - - @RequestMapping(method = RequestMethod.GET, path = "/notFound") - ResponseEntity notFound() { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body((String) null); - } - - @RequestMapping(method = RequestMethod.POST, consumes = "application/vnd.io.spring.cloud.test.v1+json", produces = "application/vnd.io.spring.cloud.test.v1+json", path = "/complex") - String complex(@RequestBody String body, @RequestHeader("Content-Length") int contentLength) { - if (contentLength <= 0) { - throw new IllegalArgumentException("Invalid Content-Length "+ contentLength); - } - return body; - } - - @RequestMapping(method = RequestMethod.GET, path = "/tostring") - String getToString(@RequestParam("arg") Arg arg) { - return arg.toString(); - } - - @RequestMapping(method = RequestMethod.GET, path = "/tostring2") - String getToString(@RequestParam("arg") OtherArg arg) { - return arg.value; - } - - @RequestMapping(method = RequestMethod.GET, path = "/tostringcollection") - Collection getToString(@RequestParam("arg") Collection args) { - List result = new ArrayList<>(); - for(OtherArg arg : args) { - result.add(arg.value); - } - return result; - } - - public static void main(String[] args) { - new SpringApplicationBuilder(Application.class) - .properties("spring.application.name=feignclienttest", - "management.contextPath=/admin") - .run(args); - } - } - - private static ArrayList getHelloList() { - ArrayList hellos = new ArrayList<>(); - hellos.add(new Hello(HELLO_WORLD_1)); - hellos.add(new Hello(OI_TERRA_2)); - return hellos; - } - - @Test - public void testClient() { - assertNotNull("testClient was null", this.testClient); - assertTrue("testClient is not a java Proxy", - Proxy.isProxyClass(this.testClient.getClass())); - InvocationHandler invocationHandler = Proxy.getInvocationHandler(this.testClient); - assertNotNull("invocationHandler was null", invocationHandler); - } - - @Test - public void testRequestMappingClassLevelPropertyReplacement() { - Hello hello = this.testClient.getHelloUsingPropertyPlaceHolder(); - assertNotNull("hello was null", hello); - assertEquals("first hello didn't match", new Hello(OI_TERRA_2), hello); - } - - @Test - public void testSimpleType() { - Hello hello = this.testClient.getHello(); - assertNotNull("hello was null", hello); - assertEquals("first hello didn't match", new Hello(HELLO_WORLD_1), hello); - } - - @Test - public void testOptional() { - Optional hello = this.testClient.getOptionalHello(); - assertThat(hello) - .isNotNull() - .isPresent() - .contains(new Hello(HELLO_WORLD_1)); - } - - @Test - public void testGenericType() { - List hellos = this.testClient.getHellos(); - assertNotNull("hellos was null", hellos); - assertEquals("hellos didn't match", hellos, getHelloList()); - } - - @Test - public void testRequestInterceptors() { - List headers = this.testClient.getHelloHeaders(); - assertNotNull("headers was null", headers); - assertTrue("headers didn't contain myheader1value", - headers.contains("myheader1value")); - assertTrue("headers didn't contain myheader2value", - headers.contains("myheader2value")); - } - - @Test - public void testHeaderPlaceholders() { - String header = this.testClient.getHelloHeadersPlaceholders(); - assertNotNull("header was null", header); - assertEquals("header was wrong", "myPlaceholderHeaderValue", header); - } - - @Test - public void testFeignClientType() throws IllegalAccessException { - assertThat(this.feignClient, is(instanceOf(LoadBalancerFeignClient.class))); - LoadBalancerFeignClient client = (LoadBalancerFeignClient) this.feignClient; - Client delegate = client.getDelegate(); - assertThat(delegate, is(instanceOf(feign.Client.Default.class))); - } - - @Test - public void testServiceId() { - assertNotNull("testClientServiceId was null", this.testClientServiceId); - final Hello hello = this.testClientServiceId.getHello(); - assertNotNull("The hello response was null", hello); - assertEquals("first hello didn't match", new Hello(HELLO_WORLD_1), hello); - } - - @Test - public void testParams() { - List list = Arrays.asList("a", "1", "test"); - List params = this.testClient.getParams(list); - assertNotNull("params was null", params); - assertEquals("params size was wrong", list.size(), params.size()); - } - - @Test - public void testHystrixCommand() throws NoSuchMethodException { - HystrixCommand> command = this.testClient.getHellosHystrix(); - assertNotNull("command was null", command); - assertEquals( - "Hystrix command group name should match the name of the feign client", - "localapp", command.getCommandGroup().name()); - String configKey = Feign.configKey(TestClient.class, - TestClient.class.getMethod("getHellosHystrix", (Class[]) null)); - assertEquals("Hystrix command key name should match the feign config key", - configKey, command.getCommandKey().name()); - List hellos = command.execute(); - assertNotNull("hellos was null", hellos); - assertEquals("hellos didn't match", hellos, getHelloList()); - } - - @Test - public void testSingle() { - Single single = this.testClient.getHelloSingle(); - assertNotNull("single was null", single); - Hello hello = single.toBlocking().value(); - assertNotNull("hello was null", hello); - assertEquals("first hello didn't match", new Hello(HELLO_WORLD_1), hello); - } - - @Test - public void testNoContentResponse() { - ResponseEntity response = testClient.noContent(); - assertNotNull("response was null", response); - assertEquals("status code was wrong", HttpStatus.NO_CONTENT, - response.getStatusCode()); - } - - @Test - public void testHeadResponse() { - ResponseEntity response = testClient.head(); - assertNotNull("response was null", response); - assertEquals("status code was wrong", HttpStatus.OK, response.getStatusCode()); - } - - @Test - public void testHttpEntity() { - HttpEntity entity = testClient.getHelloEntity(); - assertNotNull("entity was null", entity); - Hello hello = entity.getBody(); - assertNotNull("hello was null", hello); - assertEquals("first hello didn't match", new Hello(HELLO_WORLD_1), hello); - } - - @Test - public void testMoreComplexHeader() { - String response = testClient.moreComplexContentType("{\"value\":\"OK\"}"); - assertNotNull("response was null", response); - assertEquals("didn't respond with {\"value\":\"OK\"}", "{\"value\":\"OK\"}", - response); - } - - @Test - public void testDecodeNotFound() { - ResponseEntity response = decodingTestClient.notFound(); - assertNotNull("response was null", response); - assertEquals("status code was wrong", HttpStatus.NOT_FOUND, - response.getStatusCode()); - assertNull("response body was not null", response.getBody()); - } - - @Test - public void testOptionalNotFound() { - Optional s = decodingTestClient.optional(); - assertThat(s).isNotPresent(); - } - - @Test - public void testConvertingExpander() { - assertEquals(Arg.A.toString(), testClient.getToString(Arg.A)); - assertEquals(Arg.B.toString(), testClient.getToString(Arg.B)); - - assertEquals("bar", testClient.getToString(new OtherArg("foo"))); - List args = new ArrayList<>(); - args.add(new OtherArg("foo")); - args.add(new OtherArg("goo")); - List expectedResult = new ArrayList<>(); - expectedResult.add("bar"); - expectedResult.add("goo"); - assertEquals(expectedResult, testClient.getToString(args)); - } - - @Test - public void testHystrixFallbackWorks() { - Hello hello = hystrixClient.fail(); - assertNotNull("hello was null", hello); - assertEquals("message was wrong", "fallback", hello.getMessage()); - } - - @Test - public void testHystrixFallbackSingle() { - Single single = hystrixClient.failSingle(); - assertNotNull("single was null", single); - Hello hello = single.toBlocking().value(); - assertNotNull("hello was null", hello); - assertEquals("message was wrong", "fallbacksingle", hello.getMessage()); - } - - @Test - public void testHystrixFallbackCommand() { - HystrixCommand command = hystrixClient.failCommand(); - assertNotNull("command was null", command); - Hello hello = command.execute(); - assertNotNull("hello was null", hello); - assertEquals("message was wrong", "fallbackcommand", hello.getMessage()); - } - - @Test - public void testHystrixFallbackObservable() { - Observable observable = hystrixClient.failObservable(); - assertNotNull("observable was null", observable); - Hello hello = observable.toBlocking().first(); - assertNotNull("hello was null", hello); - assertEquals("message was wrong", "fallbackobservable", hello.getMessage()); - } - - @Test - public void testHystrixFallbackFuture() throws Exception { - Future future = hystrixClient.failFuture(); - assertNotNull("future was null", future); - Hello hello = future.get(1, TimeUnit.SECONDS); - assertNotNull("hello was null", hello); - assertEquals("message was wrong", "fallbackfuture", hello.getMessage()); - } - - @Test - public void testHystrixClientWithFallBackFactory() throws Exception { - Hello hello = hystrixClientWithFallBackFactory.fail(); - assertNotNull("hello was null", hello); - assertNotNull("hello#message was null", hello.getMessage()); - assertTrue("hello#message did not contain the cause (status code) of the fallback invocation", - hello.getMessage().contains("500")); - } - - @Test - public void namedFeignClientWorks() { - assertNotNull("namedHystrixClient was null", this.namedHystrixClient); - } - - @Test - public void testHystrixSetterFactory() { - HystrixCommand> command = this.hystrixSetterFactoryClient - .getHellosHystrix(); - assertNotNull("command was null", command); - String setterPrefix = TestHystrixSetterFactoryClientConfig.SETTER_PREFIX; - assertEquals( - "Hystrix command group name should match the name of the feign client with a prefix of " - + setterPrefix, setterPrefix + "localapp5", - command.getCommandGroup().name()); - assertEquals( - "Hystrix command key name should match the request method (space) request path with a prefix of " - + setterPrefix, setterPrefix + "GET /hellos", - command.getCommandKey().name()); - List hellos = command.execute(); - assertNotNull("hellos was null", hellos); - assertEquals("hellos didn't match", hellos, getHelloList()); - } - - public static class Hello { - private String message; - - public Hello() { - } - - public Hello(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Hello that = (Hello) o; - return Objects.equals(message, that.message); - } - - @Override - public int hashCode() { - return Objects.hash(message); - } - } - - @Configuration - public static class TestDefaultFeignConfig { - @Bean - Logger.Level feignLoggerLevel() { - return Logger.Level.FULL; - } - } - - // Load balancer with fixed server list for "local" pointing to localhost - @Configuration - public static class LocalRibbonClientConfiguration { - - @Value("${local.server.port}") - private int port = 0; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientValidationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientValidationTests.java deleted file mode 100644 index a3e7a50f9..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientValidationTests.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.valid; - -import org.junit.Test; -import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.cloud.netflix.feign.FeignAutoConfiguration; -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import static org.junit.Assert.assertNotNull; - -/** - * @author Dave Syer - */ -public class FeignClientValidationTests { - - @Test - public void validNotLoadBalanced() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( - GoodUrlConfiguration.class); - assertNotNull(context.getBean(GoodUrlConfiguration.Client.class)); - context.close(); - } - - @Configuration - @Import({FeignAutoConfiguration.class, HttpClientConfiguration.class}) - @EnableFeignClients(clients = GoodUrlConfiguration.Client.class) - protected static class GoodUrlConfiguration { - - @FeignClient(name="example", url="http://example.com") - interface Client { - @RequestMapping(method = RequestMethod.GET, value = "/") - @Deprecated - String get(); - } - - } - - @Test - public void validPlaceholder() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( - PlaceholderUrlConfiguration.class); - assertNotNull(context.getBean(PlaceholderUrlConfiguration.Client.class)); - context.close(); - } - - @Configuration - @Import({FeignAutoConfiguration.class, HttpClientConfiguration.class}) - @EnableFeignClients(clients = PlaceholderUrlConfiguration.Client.class) - protected static class PlaceholderUrlConfiguration { - - @FeignClient(name="example", url="${feignClient.url:http://example.com}") - interface Client { - @RequestMapping(method = RequestMethod.GET, value = "/") - @Deprecated - String get(); - } - - } - - @Test - public void validLoadBalanced() { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( - LoadBalancerAutoConfiguration.class, - RibbonAutoConfiguration.class, - FeignRibbonClientAutoConfiguration.class, - GoodServiceIdConfiguration.class); - assertNotNull(context.getBean(GoodServiceIdConfiguration.Client.class)); - context.close(); - } - - @Configuration - @Import({FeignAutoConfiguration.class, HttpClientConfiguration.class}) - @EnableFeignClients(clients = GoodServiceIdConfiguration.Client.class) - protected static class GoodServiceIdConfiguration { - - @FeignClient("foo") - interface Client { - @RequestMapping(method = RequestMethod.GET, value = "/") - @Deprecated - String get(); - } - - } - -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignHttpClientTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignHttpClientTests.java deleted file mode 100644 index e0e12b5de..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignHttpClientTests.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.valid; - -import java.util.Objects; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; - -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; - -import feign.Client; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = FeignHttpClientTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = { - "spring.application.name=feignclienttest", "feign.hystrix.enabled=false", - "feign.okhttp.enabled=false" }) -@DirtiesContext -public class FeignHttpClientTests { - - @LocalServerPort - private int port = 0; - - @Autowired - private TestClient testClient; - - @Autowired - private Client feignClient; - - @Autowired - private UserClient userClient; - - @FeignClient("localapp") - protected interface TestClient extends BaseTestClient { - } - - protected interface BaseTestClient { - @RequestMapping(method = RequestMethod.GET, value = "/hello", produces = MediaType.APPLICATION_JSON_VALUE) - Hello getHello(); - - @RequestMapping(method = RequestMethod.PATCH, value = "/hellop", consumes = "application/json") - ResponseEntity patchHello(Hello hello); - } - - protected interface UserService { - @RequestMapping(method = RequestMethod.GET, value = "/users/{id}", produces = MediaType.APPLICATION_JSON_VALUE) - User getUser(@PathVariable("id") long id); - } - - @FeignClient("localapp") - protected interface UserClient extends UserService { - } - - @Configuration - @EnableAutoConfiguration - @RestController - @EnableFeignClients(clients = { TestClient.class, UserClient.class }) - @RibbonClient(name = "localapp", configuration = LocalRibbonClientConfiguration.class) - protected static class Application implements UserService { - - @RequestMapping(method = RequestMethod.GET, value = "/hello") - public Hello getHello() { - return new Hello("hello world 1"); - } - - @RequestMapping(method = RequestMethod.PATCH, value = "/hellop") - public ResponseEntity patchHello(@RequestBody Hello hello, - @RequestHeader("Content-Length") int contentLength) { - if (contentLength <= 0) { - throw new IllegalArgumentException("Invalid Content-Length "+ contentLength); - } - if (!hello.getMessage().equals("foo")) { - throw new IllegalArgumentException("Invalid Hello: " + hello.getMessage()); - } - return ResponseEntity.ok().header("X-Hello", "hello world patch").build(); - } - - @Override - public User getUser(@PathVariable("id") long id) { - return new User("John Smith"); - } - - } - - @Test - public void testSimpleType() { - Hello hello = this.testClient.getHello(); - assertNotNull("hello was null", hello); - assertEquals("first hello didn't match", new Hello("hello world 1"), hello); - } - - @Test - public void testPatch() { - ResponseEntity response = this.testClient.patchHello(new Hello("foo")); - assertThat(response, is(notNullValue())); - String header = response.getHeaders().getFirst("X-Hello"); - assertThat(header, equalTo("hello world patch")); - } - - @Test - public void testFeignClientType() throws IllegalAccessException { - assertThat(this.feignClient, is(instanceOf(LoadBalancerFeignClient.class))); - LoadBalancerFeignClient client = (LoadBalancerFeignClient) this.feignClient; - Client delegate = client.getDelegate(); - assertThat(delegate, is(instanceOf(feign.httpclient.ApacheHttpClient.class))); - } - - @Test - public void testFeignInheritanceSupport() { - assertNotNull("UserClient was null", this.userClient); - final User user = this.userClient.getUser(1); - assertNotNull("Returned user was null", user); - assertEquals("Users were different", user, new User("John Smith")); - } - - public static class Hello { - private String message; - - public Hello() {} - - public Hello(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Hello that = (Hello) o; - return Objects.equals(message, that.message); - } - - @Override - public int hashCode() { - return Objects.hash(message); - } - } - - public static class User { - private String name; - - public User() {} - - public User(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - User that = (User) o; - return Objects.equals(name, that.name); - } - - @Override - public int hashCode() { - return Objects.hash(name); - } - } - - // Load balancer with fixed server list for "local" pointing to localhost - @Configuration - static class LocalRibbonClientConfiguration { - - @LocalServerPort - private int port = 0; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignOkHttpTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignOkHttpTests.java deleted file mode 100644 index 5defc28c0..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignOkHttpTests.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * 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.feign.valid; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; - -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; - -import feign.Client; - -import java.util.Objects; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = FeignOkHttpTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = { - "spring.application.name=feignclienttest", "feign.hystrix.enabled=false", - "feign.httpclient.enabled=false", "feign.okhttp.enabled=true", - "spring.cloud.httpclientfactories.ok.enabled=true" }) -@DirtiesContext -public class FeignOkHttpTests { - - @Value("${local.server.port}") - private int port = 0; - - @Autowired - private TestClient testClient; - - @Autowired - private Client feignClient; - - @Autowired - private UserClient userClient; - - @FeignClient("localapp") - protected interface TestClient extends BaseTestClient { - } - - protected interface BaseTestClient { - @RequestMapping(method = RequestMethod.GET, value = "/hello") - Hello getHello(); - - @RequestMapping(method = RequestMethod.PATCH, value = "/hellop", consumes = "application/json") - ResponseEntity patchHello(Hello hello); - } - - protected interface UserService { - @RequestMapping(method = RequestMethod.GET, value = "/users/{id}") - User getUser(@PathVariable("id") long id); - } - - @FeignClient("localapp") - protected interface UserClient extends UserService { - } - - @Configuration - @EnableAutoConfiguration - @RestController - @EnableFeignClients(clients = { TestClient.class, UserClient.class }) - @RibbonClient(name = "localapp", configuration = LocalRibbonClientConfiguration.class) - protected static class Application implements UserService { - - @RequestMapping(method = RequestMethod.GET, value = "/hello") - public Hello getHello() { - return new Hello("hello world 1"); - } - - @RequestMapping(method = RequestMethod.PATCH, value = "/hellop") - public ResponseEntity patchHello(@RequestBody Hello hello, - @RequestHeader("Content-Length") int contentLength) { - if (contentLength <= 0) { - throw new IllegalArgumentException("Invalid Content-Length "+ contentLength); - } - if (!hello.getMessage().equals("foo")) { - throw new IllegalArgumentException("Invalid Hello: " + hello.getMessage()); - } - return ResponseEntity.ok().header("X-Hello", "hello world patch").build(); - } - - @Override - public User getUser(@PathVariable("id") long id) { - return new User("John Smith"); - } - - } - - @Test - public void testSimpleType() { - Hello hello = this.testClient.getHello(); - assertNotNull("hello was null", hello); - assertEquals("first hello didn't match", new Hello("hello world 1"), hello); - } - - @Test - public void testPatch() { - ResponseEntity response = this.testClient.patchHello(new Hello("foo")); - assertThat(response, is(notNullValue())); - String header = response.getHeaders().getFirst("X-Hello"); - assertThat(header, equalTo("hello world patch")); - } - - @Test - public void testFeignClientType() throws IllegalAccessException { - assertThat(this.feignClient, is(instanceOf(LoadBalancerFeignClient.class))); - LoadBalancerFeignClient client = (LoadBalancerFeignClient) this.feignClient; - Client delegate = client.getDelegate(); - assertThat(delegate, is(instanceOf(feign.okhttp.OkHttpClient.class))); - } - - @Test - public void testFeignInheritanceSupport() { - assertNotNull("UserClient was null", this.userClient); - final User user = this.userClient.getUser(1); - assertNotNull("Returned user was null", user); - assertEquals("Users were different", user, new User("John Smith")); - } - - public static class Hello { - private String message; - - public Hello() { - } - - public Hello(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Hello that = (Hello) o; - return Objects.equals(message, that.message); - } - - @Override - public int hashCode() { - return Objects.hash(message); - } - } - - public static class User { - private String name; - - public User() { - } - - public User(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - User that = (User) o; - return Objects.equals(name, that.name); - } - - @Override - public int hashCode() { - return Objects.hash(name); - } - } - - // Load balancer with fixed server list for "local" pointing to localhost - @Configuration - static class LocalRibbonClientConfiguration { - - @Value("${local.server.port}") - private int port = 0; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/scanning/FeignClientEnvVarTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/scanning/FeignClientEnvVarTests.java deleted file mode 100644 index 446077447..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/scanning/FeignClientEnvVarTests.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * - * * 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. - * - */ -package org.springframework.cloud.netflix.feign.valid.scanning; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.cloud.netflix.feign.testclients.TestClient; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = FeignClientEnvVarTests.Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, value = { - "spring.application.name=feignclienttest", "feign.httpclient.enabled=false", - "basepackage=org.springframework.cloud.netflix.feign.testclients" }) -@DirtiesContext -public class FeignClientEnvVarTests { - - @Autowired - private TestClient testClient; - - @Test - public void testSimpleType() { - String hello = this.testClient.getHello(); - assertNotNull("hello was null", hello); - assertEquals("first hello didn't match", "hello world 1", hello); - } - - @Configuration - @EnableAutoConfiguration - @RestController - @EnableFeignClients(basePackages = {"${basepackage}"}) - @RibbonClient(name = "localapp", configuration = LocalRibbonClientConfiguration.class) - protected static class Application { - @RequestMapping(method = RequestMethod.GET, value = "/hello") - public String getHello() { - return "hello world 1"; - } - - } - - // Load balancer with fixed server list for "local" pointing to localhost - @Configuration - public static class LocalRibbonClientConfiguration { - - @Value("${local.server.port}") - private int port = 0; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/scanning/FeignClientScanningTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/scanning/FeignClientScanningTests.java deleted file mode 100644 index d408c52df..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/scanning/FeignClientScanningTests.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2013-2015 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.feign.valid.scanning; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; - -import feign.Client; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = FeignClientScanningTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = { - "spring.application.name=feignclienttest", "feign.httpclient.enabled=false" }) -@DirtiesContext -public class FeignClientScanningTests { - - @Value("${local.server.port}") - private int port = 0; - - @Autowired - private TestClient testClient; - - @Autowired - private TestClientByKey testClientByKey; - - @Autowired - @SuppressWarnings("unused") - private Client feignClient; - - @FeignClient("localapp") - protected interface TestClient { - @RequestMapping(method = RequestMethod.GET, value = "/hello") - String getHello(); - } - - @FeignClient("${feignClient.localappName}") - protected interface TestClientByKey { - @RequestMapping(method = RequestMethod.GET, value = "/hello") - String getHello(); - } - - @Configuration - @EnableAutoConfiguration - @RestController - @EnableFeignClients // NO clients attribute. That's what this class is testing! - @RibbonClient(name = "localapp", configuration = LocalRibbonClientConfiguration.class) - protected static class Application { - @RequestMapping(method = RequestMethod.GET, value = "/hello") - public String getHello() { - return "hello world 1"; - } - - } - - @Test - public void testSimpleType() { - String hello = this.testClient.getHello(); - assertNotNull("hello was null", hello); - assertEquals("first hello didn't match", "hello world 1", hello); - } - - @Test - public void testSimpleTypeByKey() { - String hello = this.testClientByKey.getHello(); - assertNotNull("hello was null", hello); - assertEquals("first hello didn't match", "hello world 1", hello); - } - - // Load balancer with fixed server list for "local" pointing to localhost - @Configuration - public static class LocalRibbonClientConfiguration { - - @Value("${local.server.port}") - private int port = 0; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityApplication.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityApplication.java index 7d146703b..ed01fb879 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityApplication.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityApplication.java @@ -17,8 +17,6 @@ package org.springframework.cloud.netflix.hystrix.security; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.cloud.netflix.hystrix.security.app.UsernameClient; import org.springframework.context.annotation.Configuration; /** @@ -26,7 +24,6 @@ import org.springframework.context.annotation.Configuration; */ @Configuration @SpringBootApplication -@EnableFeignClients(clients = UsernameClient.class) public class HystrixSecurityApplication { } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityTests.java deleted file mode 100644 index afba96575..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityTests.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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. - */ - -package org.springframework.cloud.netflix.hystrix.security; - -import java.util.Base64; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.hystrix.security.app.CustomConcurrenyStrategy; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.client.RestTemplate; - -import com.netflix.hystrix.strategy.HystrixPlugins; -import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests that a secured web service returning values using a feign client properly access - * the security context from a hystrix command. - * @author Daniel Lavoie - */ -@RunWith(SpringRunner.class) -@DirtiesContext -@SpringBootTest(classes = HystrixSecurityApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT, - properties = { "username.ribbon.listOfServers=localhost:${local.server.port}", - "feign.hystrix.enabled=true"}) -@ActiveProfiles("proxysecurity") -public class HystrixSecurityTests { - @Autowired - private CustomConcurrenyStrategy customConcurrenyStrategy; - - @LocalServerPort - private String serverPort; - - //TODOO: move to constants in TestAutoConfiguration - private String username = "user"; - - private String password = "password"; - - @Test - public void testSecurityConcurrencyStrategyInstalled() { - HystrixConcurrencyStrategy concurrencyStrategy = HystrixPlugins.getInstance().getConcurrencyStrategy(); - assertThat(concurrencyStrategy).isInstanceOf(SecurityContextConcurrencyStrategy.class); - } - - @Test - public void testFeignHystrixSecurity() { - HttpHeaders headers = HystrixSecurityTests.createBasicAuthHeader(username, - password); - - String usernameResult = new RestTemplate() - .exchange("http://localhost:" + serverPort + "/proxy-username", - HttpMethod.GET, new HttpEntity(headers), String.class) - .getBody(); - - Assert.assertTrue("Username should have been intercepted by feign interceptor.", - username.equals(usernameResult)); - - Assert.assertTrue("Custom hook should have been called.", - customConcurrenyStrategy.isHookCalled()); - } - - public static HttpHeaders createBasicAuthHeader(final String username, - final String password) { - return new HttpHeaders() { - private static final long serialVersionUID = 1766341693637204893L; - - { - String auth = username + ":" + password; - byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes()); - String authHeader = "Basic " + new String(encodedAuth); - this.set("Authorization", authHeader); - } - }; - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/ProxyUsernameController.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/ProxyUsernameController.java deleted file mode 100644 index 2f30427ce..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/ProxyUsernameController.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - */ - -package org.springframework.cloud.netflix.hystrix.security.app; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * @author Daniel Lavoie - */ -@RestController -@RequestMapping("/proxy-username") -public class ProxyUsernameController { - @Autowired - private UsernameClient usernameClient; - - @RequestMapping - public String getUsername() { - return usernameClient.getUsername(); - } -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/UsernameClient.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/UsernameClient.java deleted file mode 100644 index b630f839b..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/UsernameClient.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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. - */ - -package org.springframework.cloud.netflix.hystrix.security.app; - -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.web.bind.annotation.RequestMapping; - -/** - * @author Daniel Lavoie - */ -@FeignClient("username") -public interface UsernameClient { - - @RequestMapping("/username") - public String getUsername(); -} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/test/ApacheHttpClientConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/test/ApacheHttpClientConfigurationTests.java deleted file mode 100644 index c84aa21b5..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/test/ApacheHttpClientConfigurationTests.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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.test; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.concurrent.TimeUnit; - -import org.apache.http.Header; -import org.apache.http.StatusLine; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.config.RegistryBuilder; -import org.apache.http.conn.HttpClientConnectionManager; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.apache.http.message.BasicHeader; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockingDetails; -import org.mockito.Mockito; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; -import org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientConnectionManagerFactory; -import org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientFactory; -import org.springframework.cloud.netflix.feign.EnableFeignClients; -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.util.ReflectionUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.mockingDetails; - -import feign.Client; -import feign.httpclient.ApacheHttpClient; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(properties = - {"feign.okhttp.enabled: false", - "ribbon.eureka.enabled = false"}) -@DirtiesContext -public class ApacheHttpClientConfigurationTests { - - @Autowired - ApacheHttpClientConnectionManagerFactory connectionManagerFactory; - - @Autowired - ApacheHttpClientFactory httpClientFactory; - - @Autowired - LoadBalancerFeignClient feignClient; - - @Test - public void testFactories() { - assertThat(connectionManagerFactory).isInstanceOf(ApacheHttpClientConnectionManagerFactory.class); - assertThat(connectionManagerFactory).isInstanceOf(ApacheHttpClientConfigurationTestApp.MyApacheHttpClientConnectionManagerFactory.class); - assertThat(httpClientFactory).isInstanceOf(ApacheHttpClientFactory.class); - assertThat(httpClientFactory).isInstanceOf(ApacheHttpClientConfigurationTestApp.MyApacheHttpClientFactory.class); - } - - @Test - public void testHttpClientWithFeign() { - Client delegate = feignClient.getDelegate(); - assertTrue(ApacheHttpClient.class.isInstance(delegate)); - ApacheHttpClient apacheHttpClient = (ApacheHttpClient)delegate; - HttpClient httpClient = getField(apacheHttpClient, "client"); - MockingDetails httpClientDetails = mockingDetails(httpClient); - assertTrue(httpClientDetails.isMock()); - } - - protected T getField(Object target, String name) { - Field field = ReflectionUtils.findField(target.getClass(), name); - ReflectionUtils.makeAccessible(field); - Object value = ReflectionUtils.getField(field, target); - return (T)value; - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @EnableFeignClients(clients = {ApacheHttpClientConfigurationTestApp.FooClient.class}) - static class ApacheHttpClientConfigurationTestApp { - - static class MyApacheHttpClientConnectionManagerFactory extends DefaultApacheHttpClientConnectionManagerFactory { - @Override - public HttpClientConnectionManager newConnectionManager(boolean disableSslValidation, int maxTotalConnections, int maxConnectionsPerRoute, long timeToLive, TimeUnit timeUnit, RegistryBuilder registry) { - return mock(PoolingHttpClientConnectionManager.class); - } - } - - static class MyApacheHttpClientFactory extends DefaultApacheHttpClientFactory { - public MyApacheHttpClientFactory(HttpClientBuilder builder) { - super(builder); - } - - @Override - public HttpClientBuilder createBuilder() { - CloseableHttpClient client = mock(CloseableHttpClient.class); - CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - Mockito.doReturn(statusLine).when(response).getStatusLine(); - Header[] headers = new BasicHeader[0]; - doReturn(headers).when(response).getAllHeaders(); - try { - Mockito.doReturn(response).when(client).execute(any(HttpUriRequest.class)); - } catch (IOException e) { - e.printStackTrace(); - } - HttpClientBuilder builder = mock(HttpClientBuilder.class); - Mockito.doReturn(client).when(builder).build(); - return builder; - } - } - - @Configuration - static class MyConfig { - - @Bean - public ApacheHttpClientFactory apacheHttpClientFactory(HttpClientBuilder builder) { - return new MyApacheHttpClientFactory(builder); - } - - @Bean - public ApacheHttpClientConnectionManagerFactory connectionManagerFactory() { - return new MyApacheHttpClientConnectionManagerFactory(); - } - - } - - @FeignClient(name="foo", serviceId = "foo") - interface FooClient {} - } - -} - diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/test/OkHttpClientConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/test/OkHttpClientConfigurationTests.java deleted file mode 100644 index 49a47d4d5..000000000 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/test/OkHttpClientConfigurationTests.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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.test; - -import java.lang.reflect.Field; -import java.util.concurrent.TimeUnit; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockingDetails; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.httpclient.DefaultOkHttpClientConnectionPoolFactory; -import org.springframework.cloud.commons.httpclient.DefaultOkHttpClientFactory; -import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory; -import org.springframework.cloud.commons.httpclient.OkHttpClientFactory; -import org.springframework.cloud.netflix.feign.FeignClient; -import org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient; -import org.springframework.context.annotation.Bean; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.ReflectionUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.mockingDetails; - -import feign.Client; -import okhttp3.ConnectionPool; -import okhttp3.OkHttpClient; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(properties = {"feign.okhttp.enabled: true", - "spring.cloud.httpclientfactories.ok.enabled: true", "ribbon.eureka.enabled = false", "ribbon.okhttp.enabled: true", - "feign.okhttp.enabled: true", "ribbon.httpclient.enabled: false", "feign.httpclient.enabled: false"}) -@DirtiesContext -public class OkHttpClientConfigurationTests { - - @Autowired - OkHttpClientFactory okHttpClientFactory; - - @Autowired - OkHttpClientConnectionPoolFactory connectionPoolFactory; - - @Autowired - LoadBalancerFeignClient feignClient; - - @Test - public void testFactories() { - assertThat(connectionPoolFactory).isInstanceOf(OkHttpClientConnectionPoolFactory.class); - assertThat(connectionPoolFactory).isInstanceOf(TestConfig.MyOkHttpClientConnectionPoolFactory.class); - assertThat(okHttpClientFactory).isInstanceOf(OkHttpClientFactory.class); - assertThat(okHttpClientFactory).isInstanceOf(TestConfig.MyOkHttpClientFactory.class); - } - - @Test - public void testHttpClientWithFeign() { - Client delegate = feignClient.getDelegate(); - assertTrue(feign.okhttp.OkHttpClient.class.isInstance(delegate)); - feign.okhttp.OkHttpClient okHttpClient = (feign.okhttp.OkHttpClient)delegate; - OkHttpClient httpClient = getField(okHttpClient, "delegate"); - MockingDetails httpClientDetails = mockingDetails(httpClient); - assertTrue(httpClientDetails.isMock()); - } - - protected T getField(Object target, String name) { - Field field = ReflectionUtils.findField(target.getClass(), name); - ReflectionUtils.makeAccessible(field); - Object value = ReflectionUtils.getField(field, target); - return (T)value; - } - - @SpringBootConfiguration - @EnableAutoConfiguration - static class TestConfig { - - static class MyOkHttpClientConnectionPoolFactory extends DefaultOkHttpClientConnectionPoolFactory { - @Override - public ConnectionPool create(int maxIdleConnections, long keepAliveDuration, TimeUnit timeUnit) { - return new ConnectionPool(); - } - } - - static class MyOkHttpClientFactory extends DefaultOkHttpClientFactory { - public MyOkHttpClientFactory(OkHttpClient.Builder builder) { - super(builder); - } - } - - @Bean - public OkHttpClientConnectionPoolFactory connectionPoolFactory() { - return new MyOkHttpClientConnectionPoolFactory(); - } - - @Bean - public OkHttpClientFactory clientFactory(OkHttpClient.Builder builder) { - return new MyOkHttpClientFactory(builder); - } - - @Bean - public OkHttpClient client() { - return mock(OkHttpClient.class); - } - } - - @FeignClient(name="foo", serviceId = "foo") - interface FooClient {} -} diff --git a/spring-cloud-netflix-core/src/test/resources/feign-properties.properties b/spring-cloud-netflix-core/src/test/resources/feign-properties.properties deleted file mode 100644 index 27338d09d..000000000 --- a/spring-cloud-netflix-core/src/test/resources/feign-properties.properties +++ /dev/null @@ -1,21 +0,0 @@ -# This configuration used by test class org.springframework.cloud.netflix.feign.FeignClientUsingPropertiesTests - -logging.level.org.springframework.cloud.netflix.feign=debug - -feign.client.default-to-properties=true -feign.client.default-config=default - -feign.client.config.default.connectTimeout=5000 -feign.client.config.default.readTimeout=5000 -feign.client.config.default.loggerLevel=full -feign.client.config.default.errorDecoder=org.springframework.cloud.netflix.feign.FeignClientUsingPropertiesTests.DefaultErrorDecoder -feign.client.config.default.retryer=org.springframework.cloud.netflix.feign.FeignClientUsingPropertiesTests.NoRetryer -feign.client.config.default.decode404=true - -feign.client.config.foo.requestInterceptors[0]=org.springframework.cloud.netflix.feign.FeignClientUsingPropertiesTests.FooRequestInterceptor -feign.client.config.foo.requestInterceptors[1]=org.springframework.cloud.netflix.feign.FeignClientUsingPropertiesTests.BarRequestInterceptor - -feign.client.config.bar.connectTimeout=1000 -feign.client.config.bar.readTimeout=1000 - -feign.client.config.form.encoder=org.springframework.cloud.netflix.feign.FeignClientUsingPropertiesTests.FormEncoder \ No newline at end of file diff --git a/spring-cloud-netflix-dependencies/pom.xml b/spring-cloud-netflix-dependencies/pom.xml index 558916821..622d47bfe 100644 --- a/spring-cloud-netflix-dependencies/pom.xml +++ b/spring-cloud-netflix-dependencies/pom.xml @@ -55,11 +55,6 @@ spring-cloud-starter-netflix-eureka-server ${project.version} - - org.springframework.cloud - spring-cloud-starter-openfeign - ${project.version} - org.springframework.cloud spring-cloud-starter-netflix-hystrix diff --git a/spring-cloud-netflix-zuul/pom.xml b/spring-cloud-netflix-zuul/pom.xml index fe81dbccb..9ccb7eb64 100644 --- a/spring-cloud-netflix-zuul/pom.xml +++ b/spring-cloud-netflix-zuul/pom.xml @@ -122,6 +122,11 @@ okhttp test + + org.springframework.cloud + spring-cloud-openfeign-core + test + diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CustomHostRoutingFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CustomHostRoutingFilterTests.java index d7a8250dd..099788a88 100644 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CustomHostRoutingFilterTests.java +++ b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CustomHostRoutingFilterTests.java @@ -40,11 +40,11 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; import org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientFactory; -import org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientAutoConfiguration; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; import org.springframework.cloud.netflix.zuul.RoutesEndpoint; import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter; +import org.springframework.cloud.openfeign.ribbon.FeignRibbonClientAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpEntity; diff --git a/spring-cloud-starter-netflix/pom.xml b/spring-cloud-starter-netflix/pom.xml index 76aada709..af07a910a 100644 --- a/spring-cloud-starter-netflix/pom.xml +++ b/spring-cloud-starter-netflix/pom.xml @@ -22,6 +22,5 @@ spring-cloud-starter-netflix-turbine spring-cloud-starter-netflix-turbine-stream spring-cloud-starter-netflix-zuul - spring-cloud-starter-openfeign \ No newline at end of file diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-openfeign/pom.xml b/spring-cloud-starter-netflix/spring-cloud-starter-openfeign/pom.xml deleted file mode 100644 index 8e52a3537..000000000 --- a/spring-cloud-starter-netflix/spring-cloud-starter-openfeign/pom.xml +++ /dev/null @@ -1,62 +0,0 @@ - - 4.0.0 - - org.springframework.cloud - spring-cloud-starter-netflix - 2.0.0.BUILD-SNAPSHOT - - spring-cloud-starter-openfeign - Spring Cloud Starter OpenFeign - Spring Cloud Starter OpenFeign - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - ${basedir}/../../.. - - - - org.springframework.cloud - spring-cloud-starter - - - org.springframework.cloud - spring-cloud-netflix-core - - - org.springframework - spring-web - - - org.springframework.cloud - spring-cloud-commons - - - io.github.openfeign - feign-core - - - io.github.openfeign - feign-slf4j - - - io.github.openfeign - feign-hystrix - - - io.github.openfeign - feign-java8 - - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - - - org.springframework.cloud - spring-cloud-starter-netflix-archaius - - - \ No newline at end of file diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-openfeign/src/main/resources/META-INF/spring.provides b/spring-cloud-starter-netflix/spring-cloud-starter-openfeign/src/main/resources/META-INF/spring.provides deleted file mode 100644 index 3dc45a036..000000000 --- a/spring-cloud-starter-netflix/spring-cloud-starter-openfeign/src/main/resources/META-INF/spring.provides +++ /dev/null @@ -1 +0,0 @@ -provides: spring-platform-netflix-core, eureka-client \ No newline at end of file