Bumping versions
This commit is contained in:
@@ -266,14 +266,20 @@ public class FeignAutoConfiguration {
|
||||
int connectTimeout = httpClientProperties.getConnectionTimeout();
|
||||
boolean disableSslValidation = httpClientProperties.isDisableSslValidation();
|
||||
Duration readTimeout = httpClientProperties.getOkHttp().getReadTimeout();
|
||||
List<Protocol> protocols = httpClientProperties.getOkHttp().getProtocols().stream().map(Protocol::valueOf)
|
||||
.collect(Collectors.toList());
|
||||
List<Protocol> protocols = httpClientProperties.getOkHttp()
|
||||
.getProtocols()
|
||||
.stream()
|
||||
.map(Protocol::valueOf)
|
||||
.collect(Collectors.toList());
|
||||
if (disableSslValidation) {
|
||||
disableSsl(builder);
|
||||
}
|
||||
this.okHttpClient = builder.connectTimeout(connectTimeout, TimeUnit.MILLISECONDS)
|
||||
.followRedirects(followRedirects).readTimeout(readTimeout).connectionPool(connectionPool)
|
||||
.protocols(protocols).build();
|
||||
.followRedirects(followRedirects)
|
||||
.readTimeout(readTimeout)
|
||||
.connectionPool(connectionPool)
|
||||
.protocols(protocols)
|
||||
.build();
|
||||
return this.okHttpClient;
|
||||
}
|
||||
|
||||
@@ -415,11 +421,12 @@ class FeignHints implements RuntimeHintsRegistrar {
|
||||
if (!ClassUtils.isPresent("feign.Feign", classLoader)) {
|
||||
return;
|
||||
}
|
||||
hints.reflection().registerTypes(
|
||||
Set.of(TypeReference.of(FeignClientFactoryBean.class),
|
||||
TypeReference.of(ResponseInterceptor.Chain.class), TypeReference.of(Capability.class)),
|
||||
hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.DECLARED_FIELDS));
|
||||
hints.reflection()
|
||||
.registerTypes(
|
||||
Set.of(TypeReference.of(FeignClientFactoryBean.class),
|
||||
TypeReference.of(ResponseInterceptor.Chain.class), TypeReference.of(Capability.class)),
|
||||
hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.DECLARED_FIELDS));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -108,9 +108,10 @@ class FeignCircuitBreakerTargeter implements Targeter {
|
||||
}
|
||||
|
||||
private FeignCircuitBreaker.Builder builder(String feignClientName, FeignCircuitBreaker.Builder builder) {
|
||||
return builder.circuitBreakerFactory(circuitBreakerFactory).feignClientName(feignClientName)
|
||||
.circuitBreakerGroupEnabled(circuitBreakerGroupEnabled)
|
||||
.circuitBreakerNameResolver(circuitBreakerNameResolver);
|
||||
return builder.circuitBreakerFactory(circuitBreakerFactory)
|
||||
.feignClientName(feignClientName)
|
||||
.circuitBreakerGroupEnabled(circuitBreakerGroupEnabled)
|
||||
.circuitBreakerNameResolver(circuitBreakerNameResolver);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -71,9 +71,9 @@ public class FeignClientFactory extends NamedContextFactory<FeignClientSpecifica
|
||||
public FeignClientFactory withApplicationContextInitializers(Map<String, Object> applicationContextInitializers) {
|
||||
Map<String, ApplicationContextInitializer<GenericApplicationContext>> convertedInitializers = new HashMap<>();
|
||||
applicationContextInitializers.keySet()
|
||||
.forEach(contextId -> convertedInitializers.put(contextId,
|
||||
(ApplicationContextInitializer<GenericApplicationContext>) applicationContextInitializers
|
||||
.get(contextId)));
|
||||
.forEach(contextId -> convertedInitializers.put(contextId,
|
||||
(ApplicationContextInitializer<GenericApplicationContext>) applicationContextInitializers
|
||||
.get(contextId)));
|
||||
return new FeignClientFactory(convertedInitializers);
|
||||
}
|
||||
|
||||
|
||||
@@ -155,8 +155,10 @@ public class FeignClientFactoryBean
|
||||
FeignBuilderCustomizer.class);
|
||||
|
||||
if (customizerMap != null) {
|
||||
customizerMap.values().stream().sorted(AnnotationAwareOrderComparator.INSTANCE)
|
||||
.forEach(feignBuilderCustomizer -> feignBuilderCustomizer.customize(builder));
|
||||
customizerMap.values()
|
||||
.stream()
|
||||
.sorted(AnnotationAwareOrderComparator.INSTANCE)
|
||||
.forEach(feignBuilderCustomizer -> feignBuilderCustomizer.customize(builder));
|
||||
}
|
||||
additionalCustomizers.forEach(customizer -> customizer.customize(builder));
|
||||
}
|
||||
@@ -244,8 +246,10 @@ public class FeignClientFactoryBean
|
||||
|
||||
Map<String, Capability> capabilities = getInheritedAwareInstances(context, Capability.class);
|
||||
if (capabilities != null) {
|
||||
capabilities.values().stream().sorted(AnnotationAwareOrderComparator.INSTANCE)
|
||||
.forEach(builder::addCapability);
|
||||
capabilities.values()
|
||||
.stream()
|
||||
.sorted(AnnotationAwareOrderComparator.INSTANCE)
|
||||
.forEach(builder::addCapability);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,7 +338,7 @@ public class FeignClientFactoryBean
|
||||
Map<String, Collection<String>> defaultRequestHeaders = new HashMap<>();
|
||||
if (defaultConfig != null) {
|
||||
defaultConfig.getDefaultRequestHeaders()
|
||||
.forEach((k, v) -> defaultRequestHeaders.put(k, new ArrayList<>(v)));
|
||||
.forEach((k, v) -> defaultRequestHeaders.put(k, new ArrayList<>(v)));
|
||||
}
|
||||
if (clientConfig != null) {
|
||||
clientConfig.getDefaultRequestHeaders().forEach((k, v) -> defaultRequestHeaders.put(k, new ArrayList<>(v)));
|
||||
@@ -346,11 +350,11 @@ public class FeignClientFactoryBean
|
||||
Map<String, Collection<String>> defaultQueryParameters = new HashMap<>();
|
||||
if (defaultConfig != null) {
|
||||
defaultConfig.getDefaultQueryParameters()
|
||||
.forEach((k, v) -> defaultQueryParameters.put(k, new ArrayList<>(v)));
|
||||
.forEach((k, v) -> defaultQueryParameters.put(k, new ArrayList<>(v)));
|
||||
}
|
||||
if (clientConfig != null) {
|
||||
clientConfig.getDefaultQueryParameters()
|
||||
.forEach((k, v) -> defaultQueryParameters.put(k, new ArrayList<>(v)));
|
||||
.forEach((k, v) -> defaultQueryParameters.put(k, new ArrayList<>(v)));
|
||||
}
|
||||
if (!defaultQueryParameters.isEmpty()) {
|
||||
addDefaultQueryParams(defaultQueryParameters, builder);
|
||||
@@ -686,15 +690,48 @@ public class FeignClientFactoryBean
|
||||
|
||||
@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("dismiss404=").append(dismiss404).append(", ").append("inheritParentContext=")
|
||||
.append(inheritParentContext).append(", ").append("applicationContext=").append(applicationContext)
|
||||
.append(", ").append("beanFactory=").append(beanFactory).append(", ").append("fallback=")
|
||||
.append(fallback).append(", ").append("fallbackFactory=").append(fallbackFactory).append("}")
|
||||
.append("connectTimeoutMillis=").append(connectTimeoutMillis).append("}").append("readTimeoutMillis=")
|
||||
.append(readTimeoutMillis).append("}").append("followRedirects=").append(followRedirects)
|
||||
.append("refreshableClient=").append(refreshableClient).append("}").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("dismiss404=")
|
||||
.append(dismiss404)
|
||||
.append(", ")
|
||||
.append("inheritParentContext=")
|
||||
.append(inheritParentContext)
|
||||
.append(", ")
|
||||
.append("applicationContext=")
|
||||
.append(applicationContext)
|
||||
.append(", ")
|
||||
.append("beanFactory=")
|
||||
.append(beanFactory)
|
||||
.append(", ")
|
||||
.append("fallback=")
|
||||
.append(fallback)
|
||||
.append(", ")
|
||||
.append("fallbackFactory=")
|
||||
.append(fallbackFactory)
|
||||
.append("}")
|
||||
.append("connectTimeoutMillis=")
|
||||
.append(connectTimeoutMillis)
|
||||
.append("}")
|
||||
.append("readTimeoutMillis=")
|
||||
.append(readTimeoutMillis)
|
||||
.append("}")
|
||||
.append("followRedirects=")
|
||||
.append(followRedirects)
|
||||
.append("refreshableClient=")
|
||||
.append(refreshableClient)
|
||||
.append("}")
|
||||
.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -30,13 +30,14 @@ class FeignClientMicrometerEnabledCondition implements Condition {
|
||||
@Override
|
||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
FeignClientProperties feignClientProperties = context.getBeanFactory()
|
||||
.getBeanProvider(FeignClientProperties.class).getIfAvailable();
|
||||
.getBeanProvider(FeignClientProperties.class)
|
||||
.getIfAvailable();
|
||||
if (feignClientProperties != null) {
|
||||
Map<String, FeignClientProperties.FeignClientConfiguration> feignClientConfigMap = feignClientProperties
|
||||
.getConfig();
|
||||
.getConfig();
|
||||
if (feignClientConfigMap != null) {
|
||||
FeignClientProperties.FeignClientConfiguration feignClientConfig = feignClientConfigMap
|
||||
.get(context.getEnvironment().getProperty("spring.cloud.openfeign.client.name"));
|
||||
.get(context.getEnvironment().getProperty("spring.cloud.openfeign.client.name"));
|
||||
if (feignClientConfig != null) {
|
||||
FeignClientProperties.MicrometerProperties micrometer = feignClientConfig.getMicrometer();
|
||||
if (micrometer != null && micrometer.getEnabled() != null) {
|
||||
|
||||
@@ -192,7 +192,7 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLo
|
||||
Assert.isTrue(annotationMetadata.isInterface(), "@FeignClient can only be specified on an interface");
|
||||
|
||||
Map<String, Object> attributes = annotationMetadata
|
||||
.getAnnotationAttributes(FeignClient.class.getCanonicalName());
|
||||
.getAnnotationAttributes(FeignClient.class.getCanonicalName());
|
||||
|
||||
String name = getClientName(attributes);
|
||||
String className = annotationMetadata.getClassName();
|
||||
@@ -206,8 +206,9 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLo
|
||||
private void registerFeignClient(BeanDefinitionRegistry registry, AnnotationMetadata annotationMetadata,
|
||||
Map<String, Object> attributes) {
|
||||
String className = annotationMetadata.getClassName();
|
||||
if (String.valueOf(false).equals(
|
||||
environment.getProperty("spring.cloud.openfeign.lazy-attributes-resolution", String.valueOf(false)))) {
|
||||
if (String.valueOf(false)
|
||||
.equals(environment.getProperty("spring.cloud.openfeign.lazy-attributes-resolution",
|
||||
String.valueOf(false)))) {
|
||||
eagerlyRegisterFeignClientBeanDefinition(className, attributes, registry);
|
||||
}
|
||||
else {
|
||||
@@ -392,7 +393,7 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLo
|
||||
|
||||
protected Set<String> getBasePackages(AnnotationMetadata importingClassMetadata) {
|
||||
Map<String, Object> attributes = importingClassMetadata
|
||||
.getAnnotationAttributes(EnableFeignClients.class.getCanonicalName());
|
||||
.getAnnotationAttributes(EnableFeignClients.class.getCanonicalName());
|
||||
|
||||
Set<String> basePackages = new HashSet<>();
|
||||
for (String pkg : (String[]) attributes.get("value")) {
|
||||
|
||||
@@ -53,8 +53,12 @@ public class CookieValueParameterProcessor implements AnnotatedParameterProcesso
|
||||
String name = cookie.value().trim();
|
||||
checkState(emptyToNull(name) != null, "Cookie.name() was empty on parameter %s", parameterIndex);
|
||||
context.setParameterName(name);
|
||||
String cookieExpression = data.template().headers()
|
||||
.getOrDefault(HttpHeaders.COOKIE, Collections.singletonList("")).stream().findFirst().orElse("");
|
||||
String cookieExpression = data.template()
|
||||
.headers()
|
||||
.getOrDefault(HttpHeaders.COOKIE, Collections.singletonList(""))
|
||||
.stream()
|
||||
.findFirst()
|
||||
.orElse("");
|
||||
if (cookieExpression.length() == 0) {
|
||||
cookieExpression = String.format("%s={%s}", name, name);
|
||||
}
|
||||
|
||||
@@ -73,8 +73,11 @@ public class MatrixVariableParameterProcessor implements AnnotatedParameterProce
|
||||
private String expandMap(Object object) {
|
||||
Map<String, Object> paramMap = (Map) object;
|
||||
|
||||
return paramMap.keySet().stream().filter(key -> paramMap.get(key) != null)
|
||||
.map(key -> ";" + key + "=" + paramMap.get(key).toString()).collect(Collectors.joining());
|
||||
return paramMap.keySet()
|
||||
.stream()
|
||||
.filter(key -> paramMap.get(key) != null)
|
||||
.map(key -> ";" + key + "=" + paramMap.get(key).toString())
|
||||
.collect(Collectors.joining());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -70,8 +70,8 @@ public class FeignChildContextInitializer implements BeanRegistrationAotProcesso
|
||||
}
|
||||
Set<String> contextIds = new HashSet<>(getContextIdsFromConfig());
|
||||
Map<String, GenericApplicationContext> childContextAotContributions = contextIds.stream()
|
||||
.map(contextId -> Map.entry(contextId, buildChildContext(contextId)))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
.map(contextId -> Map.entry(contextId, buildChildContext(contextId)))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
return new AotContribution(childContextAotContributions);
|
||||
}
|
||||
|
||||
@@ -91,9 +91,11 @@ public class FeignChildContextInitializer implements BeanRegistrationAotProcesso
|
||||
private final Map<String, GenericApplicationContext> childContexts;
|
||||
|
||||
AotContribution(Map<String, GenericApplicationContext> childContexts) {
|
||||
this.childContexts = childContexts.entrySet().stream().filter(entry -> entry.getValue() != null)
|
||||
.map(entry -> Map.entry(entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
this.childContexts = childContexts.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> entry.getValue() != null)
|
||||
.map(entry -> Map.entry(entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,21 +105,22 @@ public class FeignChildContextInitializer implements BeanRegistrationAotProcesso
|
||||
name = name.replaceAll("[-]", "_");
|
||||
GenerationContext childGenerationContext = generationContext.withName(name);
|
||||
ClassName initializerClassName = new ApplicationContextAotGenerator()
|
||||
.processAheadOfTime(entry.getValue(), childGenerationContext);
|
||||
.processAheadOfTime(entry.getValue(), childGenerationContext);
|
||||
return Map.entry(entry.getKey(), initializerClassName);
|
||||
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
GeneratedMethod postProcessorMethod = beanRegistrationCode.getMethods()
|
||||
.add("addFeignChildContextInitializer", method -> {
|
||||
method.addJavadoc("Use AOT child context management initialization")
|
||||
.addModifiers(Modifier.PRIVATE, Modifier.STATIC)
|
||||
.addParameter(RegisteredBean.class, "registeredBean")
|
||||
.addParameter(FeignClientFactory.class, "instance").returns(FeignClientFactory.class)
|
||||
.addStatement("$T<String, Object> initializers = new $T<>()", Map.class, HashMap.class);
|
||||
generatedInitializerClassNames.keySet()
|
||||
.forEach(contextId -> method.addStatement("initializers.put($S, new $L())", contextId,
|
||||
generatedInitializerClassNames.get(contextId)));
|
||||
method.addStatement("return instance.withApplicationContextInitializers(initializers)");
|
||||
});
|
||||
.add("addFeignChildContextInitializer", method -> {
|
||||
method.addJavadoc("Use AOT child context management initialization")
|
||||
.addModifiers(Modifier.PRIVATE, Modifier.STATIC)
|
||||
.addParameter(RegisteredBean.class, "registeredBean")
|
||||
.addParameter(FeignClientFactory.class, "instance")
|
||||
.returns(FeignClientFactory.class)
|
||||
.addStatement("$T<String, Object> initializers = new $T<>()", Map.class, HashMap.class);
|
||||
generatedInitializerClassNames.keySet()
|
||||
.forEach(contextId -> method.addStatement("initializers.put($S, new $L())", contextId,
|
||||
generatedInitializerClassNames.get(contextId)));
|
||||
method.addStatement("return instance.withApplicationContextInitializers(initializers)");
|
||||
});
|
||||
beanRegistrationCode.addInstancePostProcessor(postProcessorMethod.toMethodReference());
|
||||
}
|
||||
|
||||
|
||||
@@ -88,10 +88,13 @@ public class FeignClientBeanFactoryInitializationAotProcessor
|
||||
|
||||
private Map<String, BeanDefinition> getFeignClientBeanDefinitions(FeignClientFactory feignClientFactory) {
|
||||
Map<String, FeignClientSpecification> configurations = feignClientFactory.getConfigurations();
|
||||
return configurations.values().stream().map(FeignClientSpecification::getClassName).filter(Objects::nonNull)
|
||||
.filter(className -> !className.equals("default"))
|
||||
.map(className -> Map.entry(className, context.getBeanDefinition(className)))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
return configurations.values()
|
||||
.stream()
|
||||
.map(FeignClientSpecification::getClassName)
|
||||
.filter(Objects::nonNull)
|
||||
.filter(className -> !className.equals("default"))
|
||||
.map(className -> Map.entry(className, context.getBeanDefinition(className)))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
}
|
||||
|
||||
@SuppressWarnings("NullableProblems")
|
||||
@@ -152,25 +155,28 @@ public class FeignClientBeanFactoryInitializationAotProcessor
|
||||
public void applyTo(GenerationContext generationContext,
|
||||
BeanFactoryInitializationCode beanFactoryInitializationCode) {
|
||||
RuntimeHints hints = generationContext.getRuntimeHints();
|
||||
Set<String> feignClientRegistrationMethods = feignClientBeanDefinitions.values().stream()
|
||||
.map(beanDefinition -> {
|
||||
Assert.notNull(beanDefinition, "beanDefinition cannot be null");
|
||||
Assert.isInstanceOf(GenericBeanDefinition.class, beanDefinition);
|
||||
GenericBeanDefinition registeredBeanDefinition = (GenericBeanDefinition) beanDefinition;
|
||||
MutablePropertyValues feignClientProperties = registeredBeanDefinition.getPropertyValues();
|
||||
String className = (String) feignClientProperties.get("type");
|
||||
Assert.notNull(className, "className cannot be null");
|
||||
Class<?> clazz = ClassUtils.resolveClassName(className, null);
|
||||
hints.proxies().registerJdkProxy(clazz);
|
||||
registerMethodHints(hints.reflection(), clazz);
|
||||
return beanFactoryInitializationCode.getMethods()
|
||||
.add(buildMethodName(className), method -> generateFeignClientRegistrationMethod(method,
|
||||
feignClientProperties, registeredBeanDefinition))
|
||||
.getName();
|
||||
}).collect(Collectors.toSet());
|
||||
Set<String> feignClientRegistrationMethods = feignClientBeanDefinitions.values()
|
||||
.stream()
|
||||
.map(beanDefinition -> {
|
||||
Assert.notNull(beanDefinition, "beanDefinition cannot be null");
|
||||
Assert.isInstanceOf(GenericBeanDefinition.class, beanDefinition);
|
||||
GenericBeanDefinition registeredBeanDefinition = (GenericBeanDefinition) beanDefinition;
|
||||
MutablePropertyValues feignClientProperties = registeredBeanDefinition.getPropertyValues();
|
||||
String className = (String) feignClientProperties.get("type");
|
||||
Assert.notNull(className, "className cannot be null");
|
||||
Class<?> clazz = ClassUtils.resolveClassName(className, null);
|
||||
hints.proxies().registerJdkProxy(clazz);
|
||||
registerMethodHints(hints.reflection(), clazz);
|
||||
return beanFactoryInitializationCode.getMethods()
|
||||
.add(buildMethodName(className),
|
||||
method -> generateFeignClientRegistrationMethod(method, feignClientProperties,
|
||||
registeredBeanDefinition))
|
||||
.getName();
|
||||
})
|
||||
.collect(Collectors.toSet());
|
||||
MethodReference initializerMethod = beanFactoryInitializationCode.getMethods()
|
||||
.add("initialize", method -> generateInitializerMethod(method, feignClientRegistrationMethods))
|
||||
.toMethodReference();
|
||||
.add("initialize", method -> generateInitializerMethod(method, feignClientRegistrationMethods))
|
||||
.toMethodReference();
|
||||
beanFactoryInitializationCode.addInitializer(initializerMethod);
|
||||
}
|
||||
|
||||
@@ -191,36 +197,33 @@ public class FeignClientBeanFactoryInitializationAotProcessor
|
||||
Assert.notNull(feignQualifiers, "Feign qualifiers cannot be null");
|
||||
String qualifiers = "{\"" + String.join("\",\"", (String[]) feignQualifiers) + "\"}";
|
||||
method.addJavadoc("register Feign Client: $L", feignClientPropertyValues.get("type"))
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||
.addParameter(BeanDefinitionRegistry.class, "registry")
|
||||
.addStatement("Class clazz = $T.resolveClassName(\"$L\", null)", ClassUtils.class,
|
||||
feignClientPropertyValues.get("type"))
|
||||
.addStatement("$T definition = $T.genericBeanDefinition($T.class)", BeanDefinitionBuilder.class,
|
||||
BeanDefinitionBuilder.class, FeignClientFactoryBean.class)
|
||||
.addStatement("definition.addPropertyValue(\"name\",\"$L\")", feignClientPropertyValues.get("name"))
|
||||
.addStatement("definition.addPropertyValue(\"contextId\", \"$L\")",
|
||||
feignClientPropertyValues.get("contextId"))
|
||||
.addStatement("definition.addPropertyValue(\"type\", clazz)")
|
||||
.addStatement("definition.addPropertyValue(\"url\", \"$L\")", feignClientPropertyValues.get("url"))
|
||||
.addStatement("definition.addPropertyValue(\"path\", \"$L\")",
|
||||
feignClientPropertyValues.get("path"))
|
||||
.addStatement("definition.addPropertyValue(\"dismiss404\", $L)",
|
||||
feignClientPropertyValues.get("dismiss404"))
|
||||
.addStatement("definition.addPropertyValue(\"fallback\", $T.class)",
|
||||
feignClientPropertyValues.get("fallback"))
|
||||
.addStatement("definition.addPropertyValue(\"fallbackFactory\", $T.class)",
|
||||
feignClientPropertyValues.get("fallbackFactory"))
|
||||
.addStatement("definition.setAutowireMode($L)", registeredBeanDefinition.getAutowireMode())
|
||||
.addStatement("definition.setLazyInit($L)",
|
||||
registeredBeanDefinition.getLazyInit() != null ? registeredBeanDefinition.getLazyInit()
|
||||
: false)
|
||||
.addStatement("$T beanDefinition = definition.getBeanDefinition()", AbstractBeanDefinition.class)
|
||||
.addStatement("beanDefinition.setAttribute(\"$L\", clazz)", FactoryBean.OBJECT_TYPE_ATTRIBUTE)
|
||||
.addStatement("beanDefinition.setPrimary($L)", registeredBeanDefinition.isPrimary())
|
||||
.addStatement("$T holder = new $T(beanDefinition, \"$L\", new String[]$L)",
|
||||
BeanDefinitionHolder.class, BeanDefinitionHolder.class,
|
||||
feignClientPropertyValues.get("type"), qualifiers)
|
||||
.addStatement("$T.registerBeanDefinition(holder, registry) ", BeanDefinitionReaderUtils.class);
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||
.addParameter(BeanDefinitionRegistry.class, "registry")
|
||||
.addStatement("Class clazz = $T.resolveClassName(\"$L\", null)", ClassUtils.class,
|
||||
feignClientPropertyValues.get("type"))
|
||||
.addStatement("$T definition = $T.genericBeanDefinition($T.class)", BeanDefinitionBuilder.class,
|
||||
BeanDefinitionBuilder.class, FeignClientFactoryBean.class)
|
||||
.addStatement("definition.addPropertyValue(\"name\",\"$L\")", feignClientPropertyValues.get("name"))
|
||||
.addStatement("definition.addPropertyValue(\"contextId\", \"$L\")",
|
||||
feignClientPropertyValues.get("contextId"))
|
||||
.addStatement("definition.addPropertyValue(\"type\", clazz)")
|
||||
.addStatement("definition.addPropertyValue(\"url\", \"$L\")", feignClientPropertyValues.get("url"))
|
||||
.addStatement("definition.addPropertyValue(\"path\", \"$L\")", feignClientPropertyValues.get("path"))
|
||||
.addStatement("definition.addPropertyValue(\"dismiss404\", $L)",
|
||||
feignClientPropertyValues.get("dismiss404"))
|
||||
.addStatement("definition.addPropertyValue(\"fallback\", $T.class)",
|
||||
feignClientPropertyValues.get("fallback"))
|
||||
.addStatement("definition.addPropertyValue(\"fallbackFactory\", $T.class)",
|
||||
feignClientPropertyValues.get("fallbackFactory"))
|
||||
.addStatement("definition.setAutowireMode($L)", registeredBeanDefinition.getAutowireMode())
|
||||
.addStatement("definition.setLazyInit($L)",
|
||||
registeredBeanDefinition.getLazyInit() != null ? registeredBeanDefinition.getLazyInit() : false)
|
||||
.addStatement("$T beanDefinition = definition.getBeanDefinition()", AbstractBeanDefinition.class)
|
||||
.addStatement("beanDefinition.setAttribute(\"$L\", clazz)", FactoryBean.OBJECT_TYPE_ATTRIBUTE)
|
||||
.addStatement("beanDefinition.setPrimary($L)", registeredBeanDefinition.isPrimary())
|
||||
.addStatement("$T holder = new $T(beanDefinition, \"$L\", new String[]$L)", BeanDefinitionHolder.class,
|
||||
BeanDefinitionHolder.class, feignClientPropertyValues.get("type"), qualifiers)
|
||||
.addStatement("$T.registerBeanDefinition(holder, registry) ", BeanDefinitionReaderUtils.class);
|
||||
}
|
||||
|
||||
// Visible for tests
|
||||
|
||||
@@ -40,10 +40,10 @@ public class Http2ClientFeignConfiguration {
|
||||
@ConditionalOnMissingBean
|
||||
public HttpClient.Builder httpClientBuilder(FeignHttpClientProperties httpClientProperties) {
|
||||
return HttpClient.newBuilder()
|
||||
.followRedirects(httpClientProperties.isFollowRedirects() ? HttpClient.Redirect.ALWAYS
|
||||
: HttpClient.Redirect.NEVER)
|
||||
.version(HttpClient.Version.valueOf(httpClientProperties.getHttp2().getVersion()))
|
||||
.connectTimeout(Duration.ofMillis(httpClientProperties.getConnectionTimeout()));
|
||||
.followRedirects(
|
||||
httpClientProperties.isFollowRedirects() ? HttpClient.Redirect.ALWAYS : HttpClient.Redirect.NEVER)
|
||||
.version(HttpClient.Version.valueOf(httpClientProperties.getHttp2().getVersion()))
|
||||
.connectTimeout(Duration.ofMillis(httpClientProperties.getConnectionTimeout()));
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -73,34 +73,36 @@ public class HttpClient5FeignConfiguration {
|
||||
@ConditionalOnMissingBean(HttpClientConnectionManager.class)
|
||||
public HttpClientConnectionManager hc5ConnectionManager(FeignHttpClientProperties httpClientProperties) {
|
||||
return PoolingHttpClientConnectionManagerBuilder.create()
|
||||
.setSSLSocketFactory(httpsSSLConnectionSocketFactory(httpClientProperties.isDisableSslValidation()))
|
||||
.setMaxConnTotal(httpClientProperties.getMaxConnections())
|
||||
.setMaxConnPerRoute(httpClientProperties.getMaxConnectionsPerRoute())
|
||||
.setConnPoolPolicy(PoolReusePolicy.valueOf(httpClientProperties.getHc5().getPoolReusePolicy().name()))
|
||||
.setPoolConcurrencyPolicy(
|
||||
PoolConcurrencyPolicy.valueOf(httpClientProperties.getHc5().getPoolConcurrencyPolicy().name()))
|
||||
.setConnectionTimeToLive(
|
||||
TimeValue.of(httpClientProperties.getTimeToLive(), httpClientProperties.getTimeToLiveUnit()))
|
||||
.setDefaultSocketConfig(
|
||||
SocketConfig.custom().setSoTimeout(Timeout.of(httpClientProperties.getHc5().getSocketTimeout(),
|
||||
httpClientProperties.getHc5().getSocketTimeoutUnit())).build())
|
||||
.build();
|
||||
.setSSLSocketFactory(httpsSSLConnectionSocketFactory(httpClientProperties.isDisableSslValidation()))
|
||||
.setMaxConnTotal(httpClientProperties.getMaxConnections())
|
||||
.setMaxConnPerRoute(httpClientProperties.getMaxConnectionsPerRoute())
|
||||
.setConnPoolPolicy(PoolReusePolicy.valueOf(httpClientProperties.getHc5().getPoolReusePolicy().name()))
|
||||
.setPoolConcurrencyPolicy(
|
||||
PoolConcurrencyPolicy.valueOf(httpClientProperties.getHc5().getPoolConcurrencyPolicy().name()))
|
||||
.setConnectionTimeToLive(
|
||||
TimeValue.of(httpClientProperties.getTimeToLive(), httpClientProperties.getTimeToLiveUnit()))
|
||||
.setDefaultSocketConfig(SocketConfig.custom()
|
||||
.setSoTimeout(Timeout.of(httpClientProperties.getHc5().getSocketTimeout(),
|
||||
httpClientProperties.getHc5().getSocketTimeoutUnit()))
|
||||
.build())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CloseableHttpClient httpClient5(HttpClientConnectionManager connectionManager,
|
||||
FeignHttpClientProperties httpClientProperties,
|
||||
ObjectProvider<List<HttpClientBuilderCustomizer>> customizerProvider) {
|
||||
HttpClientBuilder httpClientBuilder = HttpClients.custom().disableCookieManagement().useSystemProperties()
|
||||
.setConnectionManager(connectionManager).evictExpiredConnections()
|
||||
.setDefaultRequestConfig(RequestConfig.custom()
|
||||
.setConnectTimeout(
|
||||
Timeout.of(httpClientProperties.getConnectionTimeout(), TimeUnit.MILLISECONDS))
|
||||
.setRedirectsEnabled(httpClientProperties.isFollowRedirects())
|
||||
.setConnectionRequestTimeout(
|
||||
Timeout.of(httpClientProperties.getHc5().getConnectionRequestTimeout(),
|
||||
httpClientProperties.getHc5().getConnectionRequestTimeoutUnit()))
|
||||
.build());
|
||||
HttpClientBuilder httpClientBuilder = HttpClients.custom()
|
||||
.disableCookieManagement()
|
||||
.useSystemProperties()
|
||||
.setConnectionManager(connectionManager)
|
||||
.evictExpiredConnections()
|
||||
.setDefaultRequestConfig(RequestConfig.custom()
|
||||
.setConnectTimeout(Timeout.of(httpClientProperties.getConnectionTimeout(), TimeUnit.MILLISECONDS))
|
||||
.setRedirectsEnabled(httpClientProperties.isFollowRedirects())
|
||||
.setConnectionRequestTimeout(Timeout.of(httpClientProperties.getHc5().getConnectionRequestTimeout(),
|
||||
httpClientProperties.getHc5().getConnectionRequestTimeoutUnit()))
|
||||
.build());
|
||||
|
||||
customizerProvider.getIfAvailable(List::of).forEach(c -> c.customize(httpClientBuilder));
|
||||
|
||||
@@ -117,7 +119,8 @@ public class HttpClient5FeignConfiguration {
|
||||
|
||||
private LayeredConnectionSocketFactory httpsSSLConnectionSocketFactory(boolean isDisableSslValidation) {
|
||||
final SSLConnectionSocketFactoryBuilder sslConnectionSocketFactoryBuilder = SSLConnectionSocketFactoryBuilder
|
||||
.create().setTlsVersions(TLS.V_1_3, TLS.V_1_2);
|
||||
.create()
|
||||
.setTlsVersions(TLS.V_1_3, TLS.V_1_2);
|
||||
|
||||
if (isDisableSslValidation) {
|
||||
try {
|
||||
|
||||
@@ -75,8 +75,12 @@ public class FeignClientEncodingProperties {
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("FeignClientEncodingProperties{").append("mimeTypes=")
|
||||
.append(Arrays.toString(mimeTypes)).append(", ").append("minRequestSize=").append(minRequestSize)
|
||||
.append("}").toString();
|
||||
.append(Arrays.toString(mimeTypes))
|
||||
.append(", ")
|
||||
.append("minRequestSize=")
|
||||
.append(minRequestSize)
|
||||
.append("}")
|
||||
.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -111,9 +111,9 @@ public class FeignBlockingLoadBalancerClient implements Client {
|
||||
DefaultRequest<RequestDataContext> lbRequest = new DefaultRequest<>(
|
||||
new RequestDataContext(buildRequestData(request), hint));
|
||||
Set<LoadBalancerLifecycle> supportedLifecycleProcessors = LoadBalancerLifecycleValidator
|
||||
.getSupportedLifecycleProcessors(
|
||||
loadBalancerClientFactory.getInstances(serviceId, LoadBalancerLifecycle.class),
|
||||
RequestDataContext.class, ResponseData.class, ServiceInstance.class);
|
||||
.getSupportedLifecycleProcessors(
|
||||
loadBalancerClientFactory.getInstances(serviceId, LoadBalancerLifecycle.class),
|
||||
RequestDataContext.class, ResponseData.class, ServiceInstance.class);
|
||||
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStart(lbRequest));
|
||||
ServiceInstance instance = loadBalancerClient.choose(serviceId, lbRequest);
|
||||
org.springframework.cloud.client.loadbalancer.Response<ServiceInstance> lbResponse = new DefaultResponse(
|
||||
@@ -124,10 +124,13 @@ public class FeignBlockingLoadBalancerClient implements Client {
|
||||
LOG.warn(message);
|
||||
}
|
||||
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle
|
||||
.onComplete(new CompletionContext<ResponseData, ServiceInstance, RequestDataContext>(
|
||||
CompletionContext.Status.DISCARD, lbRequest, lbResponse)));
|
||||
return Response.builder().request(request).status(HttpStatus.SERVICE_UNAVAILABLE.value())
|
||||
.body(message, StandardCharsets.UTF_8).build();
|
||||
.onComplete(new CompletionContext<ResponseData, ServiceInstance, RequestDataContext>(
|
||||
CompletionContext.Status.DISCARD, lbRequest, lbResponse)));
|
||||
return Response.builder()
|
||||
.request(request)
|
||||
.status(HttpStatus.SERVICE_UNAVAILABLE.value())
|
||||
.body(message, StandardCharsets.UTF_8)
|
||||
.build();
|
||||
}
|
||||
String reconstructedUrl = loadBalancerClient.reconstructURI(instance, originalUri).toString();
|
||||
Request newRequest = buildRequest(request, reconstructedUrl, instance);
|
||||
|
||||
@@ -34,8 +34,13 @@ public class LoadBalancerResponseStatusCodeException extends RetryableStatusCode
|
||||
|
||||
public LoadBalancerResponseStatusCodeException(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();
|
||||
this.response = Response.builder()
|
||||
.body(new ByteArrayInputStream(body), body.length)
|
||||
.headers(response.headers())
|
||||
.reason(response.reason())
|
||||
.status(response.status())
|
||||
.request(response.request())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -55,9 +55,9 @@ final class LoadBalancerUtils {
|
||||
try {
|
||||
Response response = feignClient.execute(feignRequest, options);
|
||||
if (loadBalanced) {
|
||||
supportedLifecycleProcessors.forEach(
|
||||
lifecycle -> lifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.SUCCESS,
|
||||
lbRequest, lbResponse, buildResponseData(response))));
|
||||
supportedLifecycleProcessors
|
||||
.forEach(lifecycle -> lifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.SUCCESS,
|
||||
lbRequest, lbResponse, buildResponseData(response))));
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -137,9 +137,9 @@ public class RetryableFeignBlockingLoadBalancerClient implements Client {
|
||||
Request feignRequest = null;
|
||||
ServiceInstance retrievedServiceInstance = null;
|
||||
Set<LoadBalancerLifecycle> supportedLifecycleProcessors = LoadBalancerLifecycleValidator
|
||||
.getSupportedLifecycleProcessors(
|
||||
loadBalancerClientFactory.getInstances(serviceId, LoadBalancerLifecycle.class),
|
||||
RetryableRequestContext.class, ResponseData.class, ServiceInstance.class);
|
||||
.getSupportedLifecycleProcessors(
|
||||
loadBalancerClientFactory.getInstances(serviceId, LoadBalancerLifecycle.class),
|
||||
RetryableRequestContext.class, ResponseData.class, ServiceInstance.class);
|
||||
String hint = getHint(serviceId);
|
||||
DefaultRequest<RetryableRequestContext> lbRequest = new DefaultRequest<>(
|
||||
new RetryableRequestContext(null, buildRequestData(request), hint));
|
||||
@@ -169,8 +169,8 @@ public class RetryableFeignBlockingLoadBalancerClient implements Client {
|
||||
org.springframework.cloud.client.loadbalancer.Response<ServiceInstance> lbResponse = new DefaultResponse(
|
||||
retrievedServiceInstance);
|
||||
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle
|
||||
.onComplete(new CompletionContext<ResponseData, ServiceInstance, RetryableRequestContext>(
|
||||
CompletionContext.Status.DISCARD, lbRequest, lbResponse)));
|
||||
.onComplete(new CompletionContext<ResponseData, ServiceInstance, RetryableRequestContext>(
|
||||
CompletionContext.Status.DISCARD, lbRequest, lbResponse)));
|
||||
feignRequest = request;
|
||||
}
|
||||
else {
|
||||
@@ -179,7 +179,7 @@ public class RetryableFeignBlockingLoadBalancerClient implements Client {
|
||||
retrievedServiceInstance));
|
||||
}
|
||||
String reconstructedUrl = loadBalancerClient.reconstructURI(retrievedServiceInstance, originalUri)
|
||||
.toString();
|
||||
.toString();
|
||||
feignRequest = buildRequest(request, reconstructedUrl, retrievedServiceInstance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,8 @@ public class OAuth2AccessTokenInterceptor implements RequestInterceptor {
|
||||
}
|
||||
|
||||
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(clientRegistrationId)
|
||||
.principal(principal).build();
|
||||
.principal(principal)
|
||||
.build();
|
||||
OAuth2AuthorizedClient authorizedClient = authorizedClientManager.authorize(authorizeRequest);
|
||||
return Optional.ofNullable(authorizedClient).map(OAuth2AuthorizedClient::getAccessToken).orElse(null);
|
||||
}
|
||||
|
||||
@@ -46,10 +46,18 @@ public abstract class AbstractFormWriter extends AbstractWriter {
|
||||
@Override
|
||||
public void write(Output output, String key, Object object) throws EncodeException {
|
||||
try {
|
||||
String string = new StringBuilder().append("Content-Disposition: form-data; name=\"").append(key)
|
||||
.append('"').append(CRLF).append("Content-Type: ").append(getContentType()).append("; charset=")
|
||||
.append(output.getCharset().name()).append(CRLF).append(CRLF).append(writeAsString(object))
|
||||
.toString();
|
||||
String string = new StringBuilder().append("Content-Disposition: form-data; name=\"")
|
||||
.append(key)
|
||||
.append('"')
|
||||
.append(CRLF)
|
||||
.append("Content-Type: ")
|
||||
.append(getContentType())
|
||||
.append("; charset=")
|
||||
.append(output.getCharset().name())
|
||||
.append(CRLF)
|
||||
.append(CRLF)
|
||||
.append(writeAsString(object))
|
||||
.toString();
|
||||
|
||||
output.write(string);
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ public class SpringEncoder implements Encoder {
|
||||
private boolean shouldHaveNullCharset(HttpMessageConverter messageConverter, FeignOutputMessage outputMessage) {
|
||||
return binaryContentType(outputMessage) || messageConverter instanceof ByteArrayHttpMessageConverter
|
||||
|| messageConverter instanceof ProtobufHttpMessageConverter && ProtobufHttpMessageConverter.PROTOBUF
|
||||
.isCompatibleWith(outputMessage.getHeaders().getContentType());
|
||||
.isCompatibleWith(outputMessage.getHeaders().getContentType());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -239,9 +239,9 @@ public class SpringEncoder implements Encoder {
|
||||
protected boolean binaryContentType(FeignOutputMessage outputMessage) {
|
||||
MediaType contentType = outputMessage.getHeaders().getContentType();
|
||||
return contentType == null || Stream
|
||||
.of(MediaType.APPLICATION_CBOR, MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_PDF,
|
||||
MediaType.IMAGE_GIF, MediaType.IMAGE_JPEG, MediaType.IMAGE_PNG)
|
||||
.anyMatch(mediaType -> mediaType.includes(contentType));
|
||||
.of(MediaType.APPLICATION_CBOR, MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_PDF,
|
||||
MediaType.IMAGE_GIF, MediaType.IMAGE_JPEG, MediaType.IMAGE_PNG)
|
||||
.anyMatch(mediaType -> mediaType.includes(contentType));
|
||||
}
|
||||
|
||||
protected final class FeignOutputMessage implements HttpOutputMessage {
|
||||
|
||||
@@ -292,7 +292,7 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource
|
||||
Method method = processedMethods.get(data.configKey());
|
||||
for (Annotation parameterAnnotation : annotations) {
|
||||
AnnotatedParameterProcessor processor = annotatedArgumentProcessors
|
||||
.get(parameterAnnotation.annotationType());
|
||||
.get(parameterAnnotation.annotationType());
|
||||
if (processor != null) {
|
||||
Annotation processParameterAnnotation;
|
||||
// synthesize, handling @AliasFor, while falling back to parameter name on
|
||||
@@ -320,9 +320,9 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource
|
||||
for (int i = 0; i < paramsAnnotations.length; i++) {
|
||||
Annotation[] paramAnnotations = paramsAnnotations[i];
|
||||
Class<?> parameterType = data.method().getParameterTypes()[i];
|
||||
if (Arrays.stream(paramAnnotations).anyMatch(
|
||||
annotation -> Map.class.isAssignableFrom(parameterType) && annotation instanceof RequestParam
|
||||
|| annotation instanceof SpringQueryMap || annotation instanceof QueryMap)) {
|
||||
if (Arrays.stream(paramAnnotations)
|
||||
.anyMatch(annotation -> Map.class.isAssignableFrom(parameterType) && annotation instanceof RequestParam
|
||||
|| annotation instanceof SpringQueryMap || annotation instanceof QueryMap)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -351,8 +351,8 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource
|
||||
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()));
|
||||
md.template()
|
||||
.header(resolve(header.substring(0, index)), resolve(header.substring(index + 1).trim()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ class EagerInitFeignClientUsingConfigurerTests {
|
||||
@Test
|
||||
public void testFeignClient() {
|
||||
FeignClientFactoryBean factoryBean = (FeignClientFactoryBean) applicationContext
|
||||
.getBean(BEAN_NAME_PREFIX + "TestFeignClient");
|
||||
.getBean(BEAN_NAME_PREFIX + "TestFeignClient");
|
||||
Feign.Builder builder = factoryBean.feign(context);
|
||||
|
||||
List<RequestInterceptor> interceptors = (List) getBuilderValue(builder, "requestInterceptors");
|
||||
@@ -69,8 +69,9 @@ class EagerInitFeignClientUsingConfigurerTests {
|
||||
assertThat(getBuilderValue(builder, "logLevel")).as("log level not set").isEqualTo(Logger.Level.FULL);
|
||||
|
||||
List<Capability> capabilities = (List) getBuilderValue(builder, "capabilities");
|
||||
assertThat(capabilities).hasSize(2).hasAtLeastOneElementOfType(NoOpCapability.class)
|
||||
.hasAtLeastOneElementOfType(MicrometerObservationCapability.class);
|
||||
assertThat(capabilities).hasSize(2)
|
||||
.hasAtLeastOneElementOfType(NoOpCapability.class)
|
||||
.hasAtLeastOneElementOfType(MicrometerObservationCapability.class);
|
||||
}
|
||||
|
||||
private Object getBuilderValue(Feign.Builder builder, String member) {
|
||||
@@ -83,7 +84,7 @@ class EagerInitFeignClientUsingConfigurerTests {
|
||||
@Test
|
||||
public void testNoInheritFeignClient() {
|
||||
FeignClientFactoryBean factoryBean = (FeignClientFactoryBean) applicationContext
|
||||
.getBean(BEAN_NAME_PREFIX + "NoInheritFeignClient");
|
||||
.getBean(BEAN_NAME_PREFIX + "NoInheritFeignClient");
|
||||
Feign.Builder builder = factoryBean.feign(context);
|
||||
|
||||
List<RequestInterceptor> interceptors = (List) getBuilderValue(builder, "requestInterceptors");
|
||||
@@ -91,21 +92,23 @@ class EagerInitFeignClientUsingConfigurerTests {
|
||||
assertThat(factoryBean.isInheritParentContext()).as("is inheriting from parent configuration").isFalse();
|
||||
|
||||
List<Capability> capabilities = (List) getBuilderValue(builder, "capabilities");
|
||||
assertThat(capabilities).hasSize(2).hasAtLeastOneElementOfType(NoOpCapability.class)
|
||||
.hasAtLeastOneElementOfType(MicrometerObservationCapability.class);
|
||||
assertThat(capabilities).hasSize(2)
|
||||
.hasAtLeastOneElementOfType(NoOpCapability.class)
|
||||
.hasAtLeastOneElementOfType(MicrometerObservationCapability.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoInheritFeignClient_ignoreProperties() {
|
||||
FeignClientFactoryBean factoryBean = (FeignClientFactoryBean) applicationContext
|
||||
.getBean(BEAN_NAME_PREFIX + "NoInheritFeignClient");
|
||||
.getBean(BEAN_NAME_PREFIX + "NoInheritFeignClient");
|
||||
Feign.Builder builder = factoryBean.feign(context);
|
||||
|
||||
assertThat(getBuilderValue(builder, "logLevel")).as("log level not set").isEqualTo(Logger.Level.HEADERS);
|
||||
|
||||
List<Capability> capabilities = (List) getBuilderValue(builder, "capabilities");
|
||||
assertThat(capabilities).hasSize(2).hasAtLeastOneElementOfType(NoOpCapability.class)
|
||||
.hasAtLeastOneElementOfType(MicrometerObservationCapability.class);
|
||||
assertThat(capabilities).hasSize(2)
|
||||
.hasAtLeastOneElementOfType(NoOpCapability.class)
|
||||
.hasAtLeastOneElementOfType(MicrometerObservationCapability.class);
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
|
||||
@@ -47,8 +47,9 @@ class EnableFeignClientsTests {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
context = new SpringApplicationBuilder().web(WebApplicationType.NONE)
|
||||
.properties("debug=true", "spring.cloud.openfeign.httpclient.hc5.enabled=false")
|
||||
.sources(EnableFeignClientsTests.PlainConfiguration.class).run();
|
||||
.properties("debug=true", "spring.cloud.openfeign.httpclient.hc5.enabled=false")
|
||||
.sources(EnableFeignClientsTests.PlainConfiguration.class)
|
||||
.run();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
||||
@@ -46,57 +46,61 @@ import static org.mockito.Mockito.mock;
|
||||
class FeignAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner runner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(FeignAutoConfiguration.class))
|
||||
.withPropertyValues("spring.cloud.openfeign.httpclient.hc5.enabled=false");
|
||||
.withConfiguration(AutoConfigurations.of(FeignAutoConfiguration.class))
|
||||
.withPropertyValues("spring.cloud.openfeign.httpclient.hc5.enabled=false");
|
||||
|
||||
@Test
|
||||
void shouldInstantiateDefaultTargeterWhenFeignCircuitBreakerIsDisabled() {
|
||||
runner.withPropertyValues("spring.cloud.openfeign.circuitbreaker.enabled=false")
|
||||
.run(ctx -> assertOnlyOneTargeterPresent(ctx, DefaultTargeter.class));
|
||||
.run(ctx -> assertOnlyOneTargeterPresent(ctx, DefaultTargeter.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldInstantiateFeignCircuitBreakerTargeterWhenEnabled() {
|
||||
runner.withBean(CircuitBreakerFactory.class, () -> mock(CircuitBreakerFactory.class))
|
||||
.withPropertyValues("spring.cloud.openfeign.circuitbreaker.enabled=true").run(ctx -> {
|
||||
assertOnlyOneTargeterPresent(ctx, FeignCircuitBreakerTargeter.class);
|
||||
assertThatFeignCircuitBreakerTargeterHasGroupEnabledPropertyWithValue(ctx, false);
|
||||
assertThatFeignCircuitBreakerTargeterHasSameCircuitBreakerNameResolver(ctx,
|
||||
AlphanumericCircuitBreakerNameResolver.class);
|
||||
});
|
||||
.withPropertyValues("spring.cloud.openfeign.circuitbreaker.enabled=true")
|
||||
.run(ctx -> {
|
||||
assertOnlyOneTargeterPresent(ctx, FeignCircuitBreakerTargeter.class);
|
||||
assertThatFeignCircuitBreakerTargeterHasGroupEnabledPropertyWithValue(ctx, false);
|
||||
assertThatFeignCircuitBreakerTargeterHasSameCircuitBreakerNameResolver(ctx,
|
||||
AlphanumericCircuitBreakerNameResolver.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldInstantiateFeignCircuitBreakerTargeterWithEnabledGroup() {
|
||||
runner.withBean(CircuitBreakerFactory.class, () -> mock(CircuitBreakerFactory.class))
|
||||
.withPropertyValues("spring.cloud.openfeign.circuitbreaker.enabled=true")
|
||||
.withPropertyValues("spring.cloud.openfeign.circuitbreaker.group.enabled=true").run(ctx -> {
|
||||
assertOnlyOneTargeterPresent(ctx, FeignCircuitBreakerTargeter.class);
|
||||
assertThatFeignCircuitBreakerTargeterHasGroupEnabledPropertyWithValue(ctx, true);
|
||||
});
|
||||
.withPropertyValues("spring.cloud.openfeign.circuitbreaker.enabled=true")
|
||||
.withPropertyValues("spring.cloud.openfeign.circuitbreaker.group.enabled=true")
|
||||
.run(ctx -> {
|
||||
assertOnlyOneTargeterPresent(ctx, FeignCircuitBreakerTargeter.class);
|
||||
assertThatFeignCircuitBreakerTargeterHasGroupEnabledPropertyWithValue(ctx, true);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldInstantiateFeignCircuitBreakerTargeterWhenEnabledWithCustomCircuitBreakerNameResolver() {
|
||||
runner.withBean(CircuitBreakerFactory.class, () -> mock(CircuitBreakerFactory.class))
|
||||
.withBean(CircuitBreakerNameResolver.class, CustomCircuitBreakerNameResolver::new)
|
||||
.withPropertyValues("spring.cloud.openfeign.circuitbreaker.enabled=true").run(ctx -> {
|
||||
assertOnlyOneTargeterPresent(ctx, FeignCircuitBreakerTargeter.class);
|
||||
assertThatFeignCircuitBreakerTargeterHasSameCircuitBreakerNameResolver(ctx,
|
||||
CustomCircuitBreakerNameResolver.class);
|
||||
});
|
||||
.withBean(CircuitBreakerNameResolver.class, CustomCircuitBreakerNameResolver::new)
|
||||
.withPropertyValues("spring.cloud.openfeign.circuitbreaker.enabled=true")
|
||||
.run(ctx -> {
|
||||
assertOnlyOneTargeterPresent(ctx, FeignCircuitBreakerTargeter.class);
|
||||
assertThatFeignCircuitBreakerTargeterHasSameCircuitBreakerNameResolver(ctx,
|
||||
CustomCircuitBreakerNameResolver.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldInstantiateFeignOAuth2FeignRequestInterceptorWithoutInterceptors() {
|
||||
runner.withPropertyValues("spring.cloud.openfeign.oauth2.enabled=true",
|
||||
"spring.cloud.openfeign.oauth2.clientRegistrationId=feign-client")
|
||||
.withBean(OAuth2AuthorizedClientService.class, () -> mock(OAuth2AuthorizedClientService.class))
|
||||
.withBean(ClientRegistrationRepository.class, () -> mock(ClientRegistrationRepository.class))
|
||||
.run(ctx -> {
|
||||
assertOauth2AccessTokenInterceptorExists(ctx);
|
||||
assertThatOauth2AccessTokenInterceptorHasSpecifiedIdsPropertyWithValue(ctx, "feign-client");
|
||||
});
|
||||
runner
|
||||
.withPropertyValues("spring.cloud.openfeign.oauth2.enabled=true",
|
||||
"spring.cloud.openfeign.oauth2.clientRegistrationId=feign-client")
|
||||
.withBean(OAuth2AuthorizedClientService.class, () -> mock(OAuth2AuthorizedClientService.class))
|
||||
.withBean(ClientRegistrationRepository.class, () -> mock(ClientRegistrationRepository.class))
|
||||
.run(ctx -> {
|
||||
assertOauth2AccessTokenInterceptorExists(ctx);
|
||||
assertThatOauth2AccessTokenInterceptorHasSpecifiedIdsPropertyWithValue(ctx, "feign-client");
|
||||
});
|
||||
}
|
||||
|
||||
private void assertOauth2AccessTokenInterceptorExists(ConfigurableApplicationContext ctx) {
|
||||
@@ -111,8 +115,9 @@ class FeignAutoConfigurationTests {
|
||||
}
|
||||
|
||||
private void assertOnlyOneTargeterPresent(ConfigurableApplicationContext ctx, Class<?> beanClass) {
|
||||
assertThat(ctx.getBeansOfType(Targeter.class)).hasSize(1).hasValueSatisfying(new Condition<>(
|
||||
beanClass::isInstance, String.format("Targeter should be an instance of %s", beanClass)));
|
||||
assertThat(ctx.getBeansOfType(Targeter.class)).hasSize(1)
|
||||
.hasValueSatisfying(new Condition<>(beanClass::isInstance,
|
||||
String.format("Targeter should be an instance of %s", beanClass)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,10 @@ class FeignClientBuilderTests {
|
||||
void forType_allFieldsSetOnBuilder() {
|
||||
// when:
|
||||
final FeignClientBuilder.Builder builder = this.feignClientBuilder.forType(TestFeignClient.class, "TestClient")
|
||||
.dismiss404(true).url("Url/").path("/Path").contextId("TestContext");
|
||||
.dismiss404(true)
|
||||
.url("Url/")
|
||||
.path("/Path")
|
||||
.contextId("TestContext");
|
||||
|
||||
// then:
|
||||
assertFactoryBeanField(builder, "applicationContext", this.applicationContext);
|
||||
@@ -138,8 +141,12 @@ class FeignClientBuilderTests {
|
||||
void forType_clientFactoryBeanProvided() {
|
||||
// when:
|
||||
final FeignClientBuilder.Builder builder = this.feignClientBuilder
|
||||
.forType(TestFeignClient.class, new FeignClientFactoryBean(), "TestClient").dismiss404(true)
|
||||
.path("Path/").url("Url/").contextId("TestContext").customize(Feign.Builder::doNotCloseAfterDecode);
|
||||
.forType(TestFeignClient.class, new FeignClientFactoryBean(), "TestClient")
|
||||
.dismiss404(true)
|
||||
.path("Path/")
|
||||
.url("Url/")
|
||||
.contextId("TestContext")
|
||||
.customize(Feign.Builder::doNotCloseAfterDecode);
|
||||
|
||||
// then:
|
||||
assertFactoryBeanField(builder, "applicationContext", this.applicationContext);
|
||||
@@ -159,7 +166,7 @@ class FeignClientBuilderTests {
|
||||
void forType_build() {
|
||||
// given:
|
||||
Mockito.when(this.applicationContext.getBean(FeignClientFactory.class))
|
||||
.thenThrow(new ClosedFileSystemException()); // throw
|
||||
.thenThrow(new ClosedFileSystemException()); // throw
|
||||
// an
|
||||
// unusual
|
||||
// exception
|
||||
|
||||
@@ -60,13 +60,13 @@ public class FeignClientCacheTests {
|
||||
@Test
|
||||
void interceptedCallsReal() {
|
||||
assertThatExceptionOfType(RetryableException.class).isThrownBy(foo::getWithCache)
|
||||
.withRootCauseInstanceOf(UnknownHostException.class);
|
||||
.withRootCauseInstanceOf(UnknownHostException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void nonInterceptedCallsReal() {
|
||||
assertThatExceptionOfType(RetryableException.class).isThrownBy(foo::getWithoutCache)
|
||||
.withRootCauseInstanceOf(UnknownHostException.class);
|
||||
.withRootCauseInstanceOf(UnknownHostException.class);
|
||||
}
|
||||
|
||||
@Nested
|
||||
@@ -87,7 +87,7 @@ public class FeignClientCacheTests {
|
||||
@Test
|
||||
void nonInterceptedCallsReal() {
|
||||
assertThatExceptionOfType(RetryableException.class).isThrownBy(foo::getWithoutCache)
|
||||
.withRootCauseInstanceOf(UnknownHostException.class);
|
||||
.withRootCauseInstanceOf(UnknownHostException.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ class FeignClientDisabledClientLevelFeaturesTests {
|
||||
Map<String, Capability> barCapabilities = context.getInstances("bar", Capability.class);
|
||||
assertThat(barCapabilities).hasSize(2);
|
||||
assertThat(barCapabilities.get("micrometerObservationCapability"))
|
||||
.isExactlyInstanceOf(MicrometerObservationCapability.class);
|
||||
.isExactlyInstanceOf(MicrometerObservationCapability.class);
|
||||
assertThat(barCapabilities.get("noOpCapability")).isExactlyInstanceOf(NoOpCapability.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ public class FeignClientErrorDecoderTests {
|
||||
Object invocationHandlerLambda = ReflectionTestUtils.getField(client, "h");
|
||||
Object invocationHandler = ReflectionTestUtils.getField(invocationHandlerLambda, "arg$2");
|
||||
Map<Method, InvocationHandlerFactory.MethodHandler> dispatch = (Map<Method, InvocationHandlerFactory.MethodHandler>) ReflectionTestUtils
|
||||
.getField(invocationHandler, "dispatch");
|
||||
.getField(invocationHandler, "dispatch");
|
||||
Method key = new ArrayList<>(dispatch.keySet()).get(0);
|
||||
return ReflectionTestUtils.getField(ReflectionTestUtils.getField(dispatch.get(key), "asyncResponseHandler"),
|
||||
"errorDecoder");
|
||||
|
||||
@@ -69,18 +69,20 @@ class FeignClientFactoryBeanIntegrationTests {
|
||||
|
||||
@Test
|
||||
void shouldProcessDefaultRequestHeadersPerClient() {
|
||||
assertThat(testClientA.headers()).isNotNull().contains(entry("x-custom-header-2", List.of("2 from default")),
|
||||
entry("x-custom-header", List.of("from client A")));
|
||||
assertThat(testClientB.headers()).isNotNull().contains(entry("x-custom-header-2", List.of("2 from default")),
|
||||
entry("x-custom-header", List.of("from client B")));
|
||||
assertThat(testClientA.headers()).isNotNull()
|
||||
.contains(entry("x-custom-header-2", List.of("2 from default")),
|
||||
entry("x-custom-header", List.of("from client A")));
|
||||
assertThat(testClientB.headers()).isNotNull()
|
||||
.contains(entry("x-custom-header-2", List.of("2 from default")),
|
||||
entry("x-custom-header", List.of("from client B")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldProcessDefaultQueryParamsPerClient() {
|
||||
assertThat(testClientA.params()).isNotNull().contains(entry("customParam2", "2 from default"),
|
||||
entry("customParam1", "from client A"));
|
||||
assertThat(testClientB.params()).isNotNull().contains(entry("customParam2", "2 from default"),
|
||||
entry("customParam1", "from client B"));
|
||||
assertThat(testClientA.params()).isNotNull()
|
||||
.contains(entry("customParam2", "2 from default"), entry("customParam1", "from client A"));
|
||||
assertThat(testClientB.params()).isNotNull()
|
||||
.contains(entry("customParam2", "2 from default"), entry("customParam1", "from client B"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -60,7 +60,8 @@ class FeignClientFactoryTest {
|
||||
feignClientFactory.setConfigurations(Lists.newArrayList(getSpec("empty", null, EmptyConfiguration.class)));
|
||||
|
||||
Collection<RequestInterceptor> interceptors = feignClientFactory
|
||||
.getInstancesWithoutAncestors("empty", RequestInterceptor.class).values();
|
||||
.getInstancesWithoutAncestors("empty", RequestInterceptor.class)
|
||||
.values();
|
||||
|
||||
assertThat(interceptors).as("Interceptors is not empty").isEmpty();
|
||||
}
|
||||
@@ -89,7 +90,8 @@ class FeignClientFactoryTest {
|
||||
feignClientFactory.setConfigurations(Lists.newArrayList(getSpec("demo", null, DemoConfiguration.class)));
|
||||
|
||||
Collection<RequestInterceptor> interceptors = feignClientFactory
|
||||
.getInstancesWithoutAncestors("demo", RequestInterceptor.class).values();
|
||||
.getInstancesWithoutAncestors("demo", RequestInterceptor.class)
|
||||
.values();
|
||||
|
||||
assertThat(interceptors.size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public class FeignClientFactoryTests {
|
||||
Proxy target = context.getBean(FeignClientFactoryBean.class).getTarget();
|
||||
Object invocationHandler = ReflectionTestUtils.getField(target, "h");
|
||||
Map<Method, InvocationHandlerFactory.MethodHandler> dispatch = (Map<Method, InvocationHandlerFactory.MethodHandler>) ReflectionTestUtils
|
||||
.getField(invocationHandler, "dispatch");
|
||||
.getField(invocationHandler, "dispatch");
|
||||
Method key = new ArrayList<>(dispatch.keySet()).get(0);
|
||||
Object client = ReflectionTestUtils.getField(dispatch.get(key), "client");
|
||||
assertThat(client).isInstanceOf(Client.Default.class);
|
||||
|
||||
@@ -146,41 +146,41 @@ class FeignClientOverrideDefaultsTests {
|
||||
void exceptionPropagationPolicy() {
|
||||
assertThat(context.getInstances("foo", ExceptionPropagationPolicy.class)).isEmpty();
|
||||
assertThat(context.getInstances("bar", ExceptionPropagationPolicy.class))
|
||||
.containsValues(ExceptionPropagationPolicy.UNWRAP);
|
||||
.containsValues(ExceptionPropagationPolicy.UNWRAP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldOverrideMicrometerCapabilities() {
|
||||
// override micrometerCapability
|
||||
assertThat(context.getInstance("foo", MicrometerCapability.class))
|
||||
.isExactlyInstanceOf(TestMicrometerCapability.class);
|
||||
.isExactlyInstanceOf(TestMicrometerCapability.class);
|
||||
assertThat(context.getInstance("foo", MicrometerObservationCapability.class))
|
||||
.isExactlyInstanceOf(MicrometerObservationCapability.class);
|
||||
.isExactlyInstanceOf(MicrometerObservationCapability.class);
|
||||
Map<String, Capability> fooCapabilities = context.getInstances("foo", Capability.class);
|
||||
assertThat(fooCapabilities).hasSize(2);
|
||||
assertThat(fooCapabilities.get("micrometerCapability")).isExactlyInstanceOf(TestMicrometerCapability.class);
|
||||
assertThat(fooCapabilities.get("micrometerObservationCapability"))
|
||||
.isExactlyInstanceOf(MicrometerObservationCapability.class);
|
||||
.isExactlyInstanceOf(MicrometerObservationCapability.class);
|
||||
|
||||
// override micrometerObservationCapability
|
||||
assertThat(context.getInstance("bar", MicrometerObservationCapability.class))
|
||||
.isExactlyInstanceOf(TestMicrometerObservationCapability.class);
|
||||
.isExactlyInstanceOf(TestMicrometerObservationCapability.class);
|
||||
Map<String, Capability> barCapabilities = context.getInstances("bar", Capability.class);
|
||||
assertThat(barCapabilities).hasSize(1);
|
||||
assertThat(barCapabilities.get("micrometerCapability")).isNull();
|
||||
assertThat(barCapabilities.get("micrometerObservationCapability"))
|
||||
.isExactlyInstanceOf(TestMicrometerObservationCapability.class);
|
||||
.isExactlyInstanceOf(TestMicrometerObservationCapability.class);
|
||||
|
||||
// override both + an extra capability
|
||||
assertThat(context.getInstance("baz", MicrometerCapability.class))
|
||||
.isExactlyInstanceOf(TestMicrometerCapability.class);
|
||||
.isExactlyInstanceOf(TestMicrometerCapability.class);
|
||||
assertThat(context.getInstance("baz", MicrometerObservationCapability.class))
|
||||
.isExactlyInstanceOf(TestMicrometerObservationCapability.class);
|
||||
.isExactlyInstanceOf(TestMicrometerObservationCapability.class);
|
||||
Map<String, Capability> bazCapabilities = context.getInstances("baz", Capability.class);
|
||||
assertThat(bazCapabilities).hasSize(3);
|
||||
assertThat(bazCapabilities.get("micrometerCapability")).isExactlyInstanceOf(TestMicrometerCapability.class);
|
||||
assertThat(bazCapabilities.get("micrometerObservationCapability"))
|
||||
.isExactlyInstanceOf(TestMicrometerObservationCapability.class);
|
||||
.isExactlyInstanceOf(TestMicrometerObservationCapability.class);
|
||||
assertThat(bazCapabilities.get("noOpCapability")).isExactlyInstanceOf(NoOpCapability.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -211,13 +211,13 @@ public class FeignClientUsingPropertiesTests {
|
||||
public SingleValueClient singleValueClient() {
|
||||
this.defaultHeadersAndQuerySingleParamsFeignClientFactoryBean.setApplicationContext(this.applicationContext);
|
||||
return this.defaultHeadersAndQuerySingleParamsFeignClientFactoryBean.feign(this.context)
|
||||
.target(SingleValueClient.class, "http://localhost:" + this.port);
|
||||
.target(SingleValueClient.class, "http://localhost:" + this.port);
|
||||
}
|
||||
|
||||
public MultipleValueClient multipleValueClient() {
|
||||
this.defaultHeadersAndQueryMultipleParamsFeignClientFactoryBean.setApplicationContext(this.applicationContext);
|
||||
return this.defaultHeadersAndQueryMultipleParamsFeignClientFactoryBean.feign(this.context)
|
||||
.target(MultipleValueClient.class, "http://localhost:" + this.port);
|
||||
.target(MultipleValueClient.class, "http://localhost:" + this.port);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -228,8 +228,8 @@ public class FeignClientUsingPropertiesTests {
|
||||
readTimeoutFactoryBean.setType(FeignClientFactoryBean.class);
|
||||
readTimeoutFactoryBean.setApplicationContext(applicationContext);
|
||||
|
||||
TimeoutClient client = readTimeoutFactoryBean.feign(context).target(TimeoutClient.class,
|
||||
"http://localhost:" + port);
|
||||
TimeoutClient client = readTimeoutFactoryBean.feign(context)
|
||||
.target(TimeoutClient.class, "http://localhost:" + port);
|
||||
|
||||
Request.Options options = getRequestOptions((Proxy) client);
|
||||
|
||||
@@ -245,8 +245,8 @@ public class FeignClientUsingPropertiesTests {
|
||||
readTimeoutFactoryBean.setType(FeignClientFactoryBean.class);
|
||||
readTimeoutFactoryBean.setApplicationContext(applicationContext);
|
||||
|
||||
TimeoutClient client = readTimeoutFactoryBean.feign(context).target(TimeoutClient.class,
|
||||
"http://localhost:" + port);
|
||||
TimeoutClient client = readTimeoutFactoryBean.feign(context)
|
||||
.target(TimeoutClient.class, "http://localhost:" + port);
|
||||
|
||||
Request.Options options = getRequestOptions((Proxy) client);
|
||||
|
||||
@@ -263,8 +263,9 @@ public class FeignClientUsingPropertiesTests {
|
||||
String response = fooClient.foo();
|
||||
assertThat(response).isEqualTo("OK");
|
||||
List<Capability> capabilities = (List) ReflectionTestUtils.getField(feignBuilder, "capabilities");
|
||||
assertThat(capabilities).hasSize(2).hasAtLeastOneElementOfType(NoOpCapability.class)
|
||||
.hasAtLeastOneElementOfType(MicrometerObservationCapability.class);
|
||||
assertThat(capabilities).hasSize(2)
|
||||
.hasAtLeastOneElementOfType(NoOpCapability.class)
|
||||
.hasAtLeastOneElementOfType(MicrometerObservationCapability.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -299,7 +300,7 @@ public class FeignClientUsingPropertiesTests {
|
||||
Object invocationHandlerLambda = ReflectionTestUtils.getField(client, "h");
|
||||
Object invocationHandler = ReflectionTestUtils.getField(invocationHandlerLambda, "arg$2");
|
||||
Map<Method, InvocationHandlerFactory.MethodHandler> dispatch = (Map<Method, InvocationHandlerFactory.MethodHandler>) ReflectionTestUtils
|
||||
.getField(Objects.requireNonNull(invocationHandler), "dispatch");
|
||||
.getField(Objects.requireNonNull(invocationHandler), "dispatch");
|
||||
Method key = new ArrayList<>(dispatch.keySet()).get(0);
|
||||
return (Request.Options) ReflectionTestUtils.getField(dispatch.get(key), "options");
|
||||
}
|
||||
@@ -395,15 +396,17 @@ public class FeignClientUsingPropertiesTests {
|
||||
@GetMapping(path = "/singleValue")
|
||||
public List<String> singleValue(@RequestHeader List<String> singleValueHeaders,
|
||||
@RequestParam List<String> singleValueParameters) {
|
||||
return Stream.of(singleValueHeaders, singleValueParameters).flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
return Stream.of(singleValueHeaders, singleValueParameters)
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@GetMapping(path = "/multipleValue")
|
||||
public List<String> multipleValue(@RequestHeader List<String> multipleValueHeaders,
|
||||
@RequestParam List<String> multipleValueParameters) {
|
||||
return Stream.of(multipleValueHeaders, multipleValueParameters).flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
return Stream.of(multipleValueHeaders, multipleValueParameters)
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public class FeignClientWithRefreshableOptionsTest {
|
||||
@Test
|
||||
public void refreshScopeBeanDefinitionShouldBePresent() {
|
||||
BeanDefinition beanDefinition = ((GenericWebApplicationContext) applicationContext)
|
||||
.getBeanDefinition(Request.Options.class.getCanonicalName() + "-" + "refreshableClient");
|
||||
.getBeanDefinition(Request.Options.class.getCanonicalName() + "-" + "refreshableClient");
|
||||
BeanDefinition originBeanDefinition = beanDefinition.getOriginatingBeanDefinition();
|
||||
assertThat(originBeanDefinition.getBeanClassName()).isEqualTo(OptionsFactoryBean.class.getCanonicalName());
|
||||
assertThat(originBeanDefinition.getScope()).isEqualTo("refresh");
|
||||
|
||||
@@ -43,42 +43,44 @@ class FeignClientsMicrometerAutoConfigurationTests {
|
||||
@Test
|
||||
void shouldProvideMicrometerObservationCapability() {
|
||||
contextRunner.run(context -> assertThat(context).hasSingleBean(MicrometerObservationCapability.class)
|
||||
.doesNotHaveBean(MicrometerCapability.class));
|
||||
.doesNotHaveBean(MicrometerCapability.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotProvideMicrometerObservationCapabilityIfFeatureIsDisabled() {
|
||||
contextRunner.withPropertyValues("spring.cloud.openfeign.micrometer.enabled=false")
|
||||
.run(context -> assertThat(context).doesNotHaveBean(MicrometerObservationCapability.class)
|
||||
.doesNotHaveBean(MicrometerCapability.class));
|
||||
.run(context -> assertThat(context).doesNotHaveBean(MicrometerObservationCapability.class)
|
||||
.doesNotHaveBean(MicrometerCapability.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldProvideMicrometerCapabilityIfObservationRegistryIsMissing() {
|
||||
new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(SimpleMetricsExportAutoConfiguration.class,
|
||||
MetricsAutoConfiguration.class, FeignClientsConfiguration.class))
|
||||
.run(context -> assertThat(context).doesNotHaveBean(MicrometerObservationCapability.class)
|
||||
.hasSingleBean(MicrometerCapability.class));
|
||||
.withConfiguration(AutoConfigurations.of(SimpleMetricsExportAutoConfiguration.class,
|
||||
MetricsAutoConfiguration.class, FeignClientsConfiguration.class))
|
||||
.run(context -> assertThat(context).doesNotHaveBean(MicrometerObservationCapability.class)
|
||||
.hasSingleBean(MicrometerCapability.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotProvideMicrometerCapabilitiesIfFeignMicrometerSupportIsMissing() {
|
||||
contextRunner.withClassLoader(new FilteredClassLoader("feign.micrometer")).run(context -> assertThat(context)
|
||||
.doesNotHaveBean(MicrometerObservationCapability.class).doesNotHaveBean(MicrometerCapability.class));
|
||||
contextRunner.withClassLoader(new FilteredClassLoader("feign.micrometer"))
|
||||
.run(context -> assertThat(context).doesNotHaveBean(MicrometerObservationCapability.class)
|
||||
.doesNotHaveBean(MicrometerCapability.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotProvideMicrometerCapabilitiesIfMicrometerSupportIsMissing() {
|
||||
contextRunner.withClassLoader(new FilteredClassLoader("io.micrometer")).run(context -> assertThat(context)
|
||||
.doesNotHaveBean(MicrometerObservationCapability.class).doesNotHaveBean(MicrometerCapability.class));
|
||||
contextRunner.withClassLoader(new FilteredClassLoader("io.micrometer"))
|
||||
.run(context -> assertThat(context).doesNotHaveBean(MicrometerObservationCapability.class)
|
||||
.doesNotHaveBean(MicrometerCapability.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotProvideMicrometerCapabilitiesIfBeansAreMissing() {
|
||||
new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(FeignClientsConfiguration.class))
|
||||
.run(context -> assertThat(context).doesNotHaveBean(MicrometerObservationCapability.class)
|
||||
.doesNotHaveBean(MicrometerCapability.class));
|
||||
.run(context -> assertThat(context).doesNotHaveBean(MicrometerObservationCapability.class)
|
||||
.doesNotHaveBean(MicrometerCapability.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -92,13 +92,13 @@ class FeignClientsRegistrarTests {
|
||||
@Test
|
||||
void testFallback() {
|
||||
assertThatExceptionOfType(IllegalArgumentException.class)
|
||||
.isThrownBy(() -> new AnnotationConfigApplicationContext(FallbackTestConfig.class));
|
||||
.isThrownBy(() -> new AnnotationConfigApplicationContext(FallbackTestConfig.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFallbackFactory() {
|
||||
assertThatExceptionOfType(IllegalArgumentException.class)
|
||||
.isThrownBy(() -> new AnnotationConfigApplicationContext(FallbackFactoryTestConfig.class));
|
||||
.isThrownBy(() -> new AnnotationConfigApplicationContext(FallbackFactoryTestConfig.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -107,8 +107,8 @@ class FeignClientsRegistrarTests {
|
||||
((DefaultListableBeanFactory) context.getBeanFactory()).setAllowBeanDefinitionOverriding(false);
|
||||
context.register(TopLevelSubLevelTestConfig.class);
|
||||
assertThatCode(context::refresh)
|
||||
.as("Case https://github.com/spring-cloud/spring-cloud-openfeign/issues/331 should be solved")
|
||||
.doesNotThrowAnyException();
|
||||
.as("Case https://github.com/spring-cloud/spring-cloud-openfeign/issues/331 should be solved")
|
||||
.doesNotThrowAnyException();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -123,7 +123,7 @@ class FeignClientsRegistrarTests {
|
||||
|
||||
Object invocationHandlerLambda = ReflectionTestUtils.getField(feignClientBean, "h");
|
||||
Target.HardCodedTarget<NullUrlFeignClient> target = (Target.HardCodedTarget<NullUrlFeignClient>) ReflectionTestUtils
|
||||
.getField(invocationHandlerLambda, "arg$3");
|
||||
.getField(invocationHandlerLambda, "arg$3");
|
||||
assertThat(target.name()).isEqualTo("nullUrlFeignClient");
|
||||
assertThat(target.url()).isEqualTo("http://nullUrlFeignClient");
|
||||
}
|
||||
|
||||
@@ -41,39 +41,37 @@ class FeignCompressionTests {
|
||||
@Test
|
||||
void shouldAddCompressionInterceptors() {
|
||||
new ApplicationContextRunner()
|
||||
.withPropertyValues("spring.cloud.openfeign.compression.response.enabled=true",
|
||||
"spring.cloud.openfeign.compression.request.enabled=true",
|
||||
"spring.cloud.openfeign.okhttp.enabled=false")
|
||||
.withConfiguration(AutoConfigurations.of(FeignAutoConfiguration.class,
|
||||
FeignContentGzipEncodingAutoConfiguration.class,
|
||||
FeignAcceptGzipEncodingAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
FeignClientFactory feignClientFactory = context.getBean(FeignClientFactory.class);
|
||||
Map<String, RequestInterceptor> interceptors = feignClientFactory.getInstances("foo",
|
||||
RequestInterceptor.class);
|
||||
assertThat(interceptors.size()).isEqualTo(2);
|
||||
assertThat(interceptors.get("feignAcceptGzipEncodingInterceptor"))
|
||||
.isInstanceOf(FeignAcceptGzipEncodingInterceptor.class);
|
||||
assertThat(interceptors.get("feignContentGzipEncodingInterceptor"))
|
||||
.isInstanceOf(FeignContentGzipEncodingInterceptor.class);
|
||||
});
|
||||
.withPropertyValues("spring.cloud.openfeign.compression.response.enabled=true",
|
||||
"spring.cloud.openfeign.compression.request.enabled=true",
|
||||
"spring.cloud.openfeign.okhttp.enabled=false")
|
||||
.withConfiguration(AutoConfigurations.of(FeignAutoConfiguration.class,
|
||||
FeignContentGzipEncodingAutoConfiguration.class, FeignAcceptGzipEncodingAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
FeignClientFactory feignClientFactory = context.getBean(FeignClientFactory.class);
|
||||
Map<String, RequestInterceptor> interceptors = feignClientFactory.getInstances("foo",
|
||||
RequestInterceptor.class);
|
||||
assertThat(interceptors.size()).isEqualTo(2);
|
||||
assertThat(interceptors.get("feignAcceptGzipEncodingInterceptor"))
|
||||
.isInstanceOf(FeignAcceptGzipEncodingInterceptor.class);
|
||||
assertThat(interceptors.get("feignContentGzipEncodingInterceptor"))
|
||||
.isInstanceOf(FeignContentGzipEncodingInterceptor.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotAddInterceptorsIfFeignOkHttpClientPresent() {
|
||||
new ApplicationContextRunner()
|
||||
.withPropertyValues("spring.cloud.openfeign.compression.response.enabled=true",
|
||||
"spring.cloud.openfeign.compression.request.enabled=true",
|
||||
"spring.cloud.openfeign.okhttp.enabled=true", "spring.cloud.openfeign.httpclient.hc5.enabled")
|
||||
.withConfiguration(AutoConfigurations.of(FeignAutoConfiguration.class,
|
||||
FeignContentGzipEncodingAutoConfiguration.class,
|
||||
FeignAcceptGzipEncodingAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
FeignClientFactory feignClientFactory = context.getBean(FeignClientFactory.class);
|
||||
Map<String, RequestInterceptor> interceptors = feignClientFactory.getInstances("foo",
|
||||
RequestInterceptor.class);
|
||||
assertThat(interceptors).isEmpty();
|
||||
});
|
||||
.withPropertyValues("spring.cloud.openfeign.compression.response.enabled=true",
|
||||
"spring.cloud.openfeign.compression.request.enabled=true",
|
||||
"spring.cloud.openfeign.okhttp.enabled=true", "spring.cloud.openfeign.httpclient.hc5.enabled")
|
||||
.withConfiguration(AutoConfigurations.of(FeignAutoConfiguration.class,
|
||||
FeignContentGzipEncodingAutoConfiguration.class, FeignAcceptGzipEncodingAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
FeignClientFactory feignClientFactory = context.getBean(FeignClientFactory.class);
|
||||
Map<String, RequestInterceptor> interceptors = feignClientFactory.getInstances("foo",
|
||||
RequestInterceptor.class);
|
||||
assertThat(interceptors).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -41,10 +41,12 @@ class FeignHttp2ClientConfigurationTests {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
context = new SpringApplicationBuilder()
|
||||
.properties("debug=true", "spring.cloud.openfeign.http2client.enabled=true",
|
||||
"spring.cloud.openfeign.httpclient.http2.version=HTTP_1_1",
|
||||
"spring.cloud.openfeign.httpclient.connectionTimeout=15")
|
||||
.web(WebApplicationType.NONE).sources(FeignAutoConfiguration.class).run();
|
||||
.properties("debug=true", "spring.cloud.openfeign.http2client.enabled=true",
|
||||
"spring.cloud.openfeign.httpclient.http2.version=HTTP_1_1",
|
||||
"spring.cloud.openfeign.httpclient.connectionTimeout=15")
|
||||
.web(WebApplicationType.NONE)
|
||||
.sources(FeignAutoConfiguration.class)
|
||||
.run();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
||||
@@ -57,7 +57,8 @@ class FeignHttpClient5ConfigurationTests {
|
||||
@Test
|
||||
void shouldInstantiateHttpClient5ByDefaultWhenDependenciesPresent() {
|
||||
ConfigurableApplicationContext context = new SpringApplicationBuilder().web(WebApplicationType.NONE)
|
||||
.sources(FeignAutoConfiguration.class).run();
|
||||
.sources(FeignAutoConfiguration.class)
|
||||
.run();
|
||||
|
||||
verifyHc5BeansAvailable(context);
|
||||
|
||||
@@ -69,11 +70,13 @@ class FeignHttpClient5ConfigurationTests {
|
||||
@Test
|
||||
void shouldNotInstantiateHttpClient5ByWhenDependenciesPresentButPropertyDisabled() {
|
||||
ConfigurableApplicationContext context = new SpringApplicationBuilder()
|
||||
.properties("spring.cloud.openfeign.httpclient.hc5.enabled=false").web(WebApplicationType.NONE)
|
||||
.sources(FeignAutoConfiguration.class).run();
|
||||
.properties("spring.cloud.openfeign.httpclient.hc5.enabled=false")
|
||||
.web(WebApplicationType.NONE)
|
||||
.sources(FeignAutoConfiguration.class)
|
||||
.run();
|
||||
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
||||
.isThrownBy(() -> context.getBean(CloseableHttpClient.class));
|
||||
.isThrownBy(() -> context.getBean(CloseableHttpClient.class));
|
||||
|
||||
if (context != null) {
|
||||
context.close();
|
||||
@@ -83,7 +86,8 @@ class FeignHttpClient5ConfigurationTests {
|
||||
@Test
|
||||
void shouldInstantiateHttpClient5ByUsingHttpClientBuilderCustomizer() {
|
||||
ConfigurableApplicationContext context = new SpringApplicationBuilder().web(WebApplicationType.NONE)
|
||||
.sources(FeignAutoConfiguration.class, Config.class).run();
|
||||
.sources(FeignAutoConfiguration.class, Config.class)
|
||||
.run();
|
||||
|
||||
CloseableHttpClient httpClient = context.getBean(CloseableHttpClient.class);
|
||||
assertThat(httpClient).isNotNull();
|
||||
|
||||
@@ -44,12 +44,13 @@ class FeignOkHttpConfigurationTests {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
this.context = new SpringApplicationBuilder()
|
||||
.properties("debug=true", "spring.cloud.openfeign.httpclient.disableSslValidation=true",
|
||||
"spring.cloud.openfeign.okhttp.enabled=true",
|
||||
"spring.cloud.openfeign.httpclient.hc5.enabled=false",
|
||||
"spring.cloud.openfeign.httpclient.okhttp.read-timeout=9s",
|
||||
"spring.cloud.openfeign.httpclient.okhttp.protocols=H2_PRIOR_KNOWLEDGE")
|
||||
.web(WebApplicationType.NONE).sources(FeignAutoConfiguration.class).run();
|
||||
.properties("debug=true", "spring.cloud.openfeign.httpclient.disableSslValidation=true",
|
||||
"spring.cloud.openfeign.okhttp.enabled=true", "spring.cloud.openfeign.httpclient.hc5.enabled=false",
|
||||
"spring.cloud.openfeign.httpclient.okhttp.read-timeout=9s",
|
||||
"spring.cloud.openfeign.httpclient.okhttp.protocols=H2_PRIOR_KNOWLEDGE")
|
||||
.web(WebApplicationType.NONE)
|
||||
.sources(FeignAutoConfiguration.class)
|
||||
.run();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
@@ -64,7 +65,7 @@ class FeignOkHttpConfigurationTests {
|
||||
OkHttpClient httpClient = context.getBean(OkHttpClient.class);
|
||||
HostnameVerifier hostnameVerifier = (HostnameVerifier) this.getField(httpClient, "hostnameVerifier");
|
||||
assertThat(hostnameVerifier instanceof FeignAutoConfiguration.OkHttpFeignConfiguration.TrustAllHostnames)
|
||||
.isTrue();
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -63,8 +63,8 @@ class LazyInitFeignClientUsingConfigurerTests {
|
||||
@Test
|
||||
void testFeignClient() {
|
||||
FeignClientFactoryBean factoryBean = (FeignClientFactoryBean) beanFactory
|
||||
.getBeanDefinition(BEAN_NAME_PREFIX + "TestFeignClient")
|
||||
.getAttribute("feignClientsRegistrarFactoryBean");
|
||||
.getBeanDefinition(BEAN_NAME_PREFIX + "TestFeignClient")
|
||||
.getAttribute("feignClientsRegistrarFactoryBean");
|
||||
Feign.Builder builder = factoryBean.feign(context);
|
||||
|
||||
List<RequestInterceptor> interceptors = (List) getBuilderValue(builder, "requestInterceptors");
|
||||
@@ -72,8 +72,9 @@ class LazyInitFeignClientUsingConfigurerTests {
|
||||
assertThat(getBuilderValue(builder, "logLevel")).as("log level not set").isEqualTo(Logger.Level.FULL);
|
||||
|
||||
List<Capability> capabilities = (List) getBuilderValue(builder, "capabilities");
|
||||
assertThat(capabilities).hasSize(2).hasAtLeastOneElementOfType(NoOpCapability.class)
|
||||
.hasAtLeastOneElementOfType(MicrometerObservationCapability.class);
|
||||
assertThat(capabilities).hasSize(2)
|
||||
.hasAtLeastOneElementOfType(NoOpCapability.class)
|
||||
.hasAtLeastOneElementOfType(MicrometerObservationCapability.class);
|
||||
}
|
||||
|
||||
private Object getBuilderValue(Feign.Builder builder, String member) {
|
||||
@@ -87,8 +88,8 @@ class LazyInitFeignClientUsingConfigurerTests {
|
||||
@Test
|
||||
void testNoInheritFeignClient() {
|
||||
FeignClientFactoryBean factoryBean = (FeignClientFactoryBean) beanFactory
|
||||
.getBeanDefinition(BEAN_NAME_PREFIX + "NoInheritFeignClient")
|
||||
.getAttribute("feignClientsRegistrarFactoryBean");
|
||||
.getBeanDefinition(BEAN_NAME_PREFIX + "NoInheritFeignClient")
|
||||
.getAttribute("feignClientsRegistrarFactoryBean");
|
||||
Feign.Builder builder = factoryBean.feign(context);
|
||||
|
||||
List<RequestInterceptor> interceptors = (List) getBuilderValue(builder, "requestInterceptors");
|
||||
@@ -96,23 +97,25 @@ class LazyInitFeignClientUsingConfigurerTests {
|
||||
assertThat(factoryBean.isInheritParentContext()).as("is inheriting from parent configuration").isFalse();
|
||||
|
||||
List<Capability> capabilities = (List) getBuilderValue(builder, "capabilities");
|
||||
assertThat(capabilities).hasSize(2).hasAtLeastOneElementOfType(NoOpCapability.class)
|
||||
.hasAtLeastOneElementOfType(MicrometerObservationCapability.class);
|
||||
assertThat(capabilities).hasSize(2)
|
||||
.hasAtLeastOneElementOfType(NoOpCapability.class)
|
||||
.hasAtLeastOneElementOfType(MicrometerObservationCapability.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
void testNoInheritFeignClient_ignoreProperties() {
|
||||
FeignClientFactoryBean factoryBean = (FeignClientFactoryBean) beanFactory
|
||||
.getBeanDefinition(BEAN_NAME_PREFIX + "NoInheritFeignClient")
|
||||
.getAttribute("feignClientsRegistrarFactoryBean");
|
||||
.getBeanDefinition(BEAN_NAME_PREFIX + "NoInheritFeignClient")
|
||||
.getAttribute("feignClientsRegistrarFactoryBean");
|
||||
Feign.Builder builder = factoryBean.feign(context);
|
||||
|
||||
assertThat(getBuilderValue(builder, "logLevel")).as("log level not set").isEqualTo(Logger.Level.HEADERS);
|
||||
|
||||
List<Capability> capabilities = (List) getBuilderValue(builder, "capabilities");
|
||||
assertThat(capabilities).hasSize(2).hasAtLeastOneElementOfType(NoOpCapability.class)
|
||||
.hasAtLeastOneElementOfType(MicrometerObservationCapability.class);
|
||||
assertThat(capabilities).hasSize(2)
|
||||
.hasAtLeastOneElementOfType(NoOpCapability.class)
|
||||
.hasAtLeastOneElementOfType(MicrometerObservationCapability.class);
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
|
||||
@@ -44,8 +44,12 @@ public class OptionsTestClient implements Client {
|
||||
|
||||
@Override
|
||||
public Response execute(Request request, Request.Options options) {
|
||||
return Response.builder().status(200).request(request).headers(headers()).body(prepareResponse(options))
|
||||
.build();
|
||||
return Response.builder()
|
||||
.status(200)
|
||||
.request(request)
|
||||
.headers(headers())
|
||||
.body(prepareResponse(options))
|
||||
.build();
|
||||
}
|
||||
|
||||
private Map<String, Collection<String>> headers() {
|
||||
|
||||
@@ -98,8 +98,9 @@ class RefreshableFeignClientUrlTests {
|
||||
UrlTestClient.UrlResponseForTests response = client.refreshable();
|
||||
assertThat(response.getUrl()).isEqualTo("http://localhost:8080/common/refreshable");
|
||||
|
||||
clientProperties.getConfig().get("refreshableClientForContextRefreshCaseWithPath")
|
||||
.setUrl("http://localhost:8888");
|
||||
clientProperties.getConfig()
|
||||
.get("refreshableClientForContextRefreshCaseWithPath")
|
||||
.setUrl("http://localhost:8888");
|
||||
refreshScope.refreshAll();
|
||||
response = client.refreshable();
|
||||
assertThat(response.getUrl()).isEqualTo("http://localhost:8888/common/refreshable");
|
||||
|
||||
@@ -50,7 +50,7 @@ class SpringDecoderTests {
|
||||
void shouldNotThrownNPEWhenNoContent() {
|
||||
assertThatCode(
|
||||
() -> decoder.decode(Response.builder().request(mock(Request.class)).status(200).build(), String.class))
|
||||
.doesNotThrowAnyException();
|
||||
.doesNotThrowAnyException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,8 +43,12 @@ public class UrlTestClient implements Client {
|
||||
|
||||
@Override
|
||||
public Response execute(Request request, Request.Options options) {
|
||||
return Response.builder().status(200).request(request).headers(headers()).body(prepareResponse(request))
|
||||
.build();
|
||||
return Response.builder()
|
||||
.status(200)
|
||||
.request(request)
|
||||
.headers(headers())
|
||||
.body(prepareResponse(request))
|
||||
.build();
|
||||
}
|
||||
|
||||
private Map<String, Collection<String>> headers() {
|
||||
|
||||
@@ -77,10 +77,10 @@ public class FeignAotTests {
|
||||
void shouldStartFeignChildContextsFromAotContributions(CapturedOutput output) {
|
||||
WebApplicationContextRunner contextRunner = new WebApplicationContextRunner(
|
||||
AnnotationConfigServletWebApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class,
|
||||
FeignAutoConfiguration.class))
|
||||
.withConfiguration(UserConfigurations.of(TestFeignConfiguration.class))
|
||||
.withPropertyValues("logging.level.org.springframework.cloud=DEBUG");
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class, FeignAutoConfiguration.class))
|
||||
.withConfiguration(UserConfigurations.of(TestFeignConfiguration.class))
|
||||
.withPropertyValues("logging.level.org.springframework.cloud=DEBUG");
|
||||
contextRunner.prepare(context -> {
|
||||
TestGenerationContext generationContext = new TestGenerationContext(TestTarget.class);
|
||||
ClassName className = new ApplicationContextAotGenerator().processAheadOfTime(
|
||||
@@ -90,14 +90,14 @@ public class FeignAotTests {
|
||||
compiler.with(generationContext).compile(compiled -> {
|
||||
ServletWebServerApplicationContext freshApplicationContext = new ServletWebServerApplicationContext();
|
||||
ApplicationContextInitializer<GenericApplicationContext> initializer = compiled
|
||||
.getInstance(ApplicationContextInitializer.class, className.toString());
|
||||
.getInstance(ApplicationContextInitializer.class, className.toString());
|
||||
initializer.initialize(freshApplicationContext);
|
||||
assertThat(output).contains("Refreshing FeignClientFactory-test-with-config",
|
||||
"Refreshing FeignClientFactory-test");
|
||||
assertThat(output).doesNotContain("Instantiating bean from Test custom config",
|
||||
"Instantiating bean from default custom config");
|
||||
TestPropertyValues.of(AotDetector.AOT_ENABLED + "=true")
|
||||
.applyToSystemProperties(freshApplicationContext::refresh);
|
||||
.applyToSystemProperties(freshApplicationContext::refresh);
|
||||
assertThat(output).contains("Instantiating bean from Test custom config",
|
||||
"Instantiating bean from default custom config");
|
||||
assertThat(freshApplicationContext.getBean(TestFeignClient.class)).isNotNull();
|
||||
|
||||
@@ -99,7 +99,7 @@ class FeignClientBeanFactoryInitializationAotProcessorTests {
|
||||
private static void verifyContribution(
|
||||
FeignClientBeanFactoryInitializationAotProcessor.AotContribution contribution) {
|
||||
BeanDefinition contributionBeanDefinition = contribution.getFeignClientBeanDefinitions()
|
||||
.get(TestClient.class.getCanonicalName());
|
||||
.get(TestClient.class.getCanonicalName());
|
||||
assertThat(contributionBeanDefinition.getBeanClassName()).isEqualTo(BEAN_DEFINITION_CLASS_NAME);
|
||||
PropertyValues propertyValues = contributionBeanDefinition.getPropertyValues();
|
||||
assertThat(propertyValues).isNotEmpty();
|
||||
|
||||
@@ -100,7 +100,7 @@ public class BeansFeignClientTests {
|
||||
void buildByBuilder() {
|
||||
assertThat(this.buildByBuilder).as("buildByBuilder was null").isNotNull();
|
||||
assertThat(Proxy.isProxyClass(this.buildByBuilder.getClass())).as("buildByBuilder is not a java Proxy")
|
||||
.isTrue();
|
||||
.isTrue();
|
||||
InvocationHandler invocationHandler = Proxy.getInvocationHandler(this.buildByBuilder);
|
||||
assertThat(invocationHandler).as("invocationHandler was null").isNotNull();
|
||||
}
|
||||
|
||||
@@ -79,28 +79,35 @@ class AsyncCircuitBreakerTests {
|
||||
|
||||
@Test
|
||||
void shouldWorkNormally() throws Exception {
|
||||
mvc.perform(get("/hello/proxy")).andDo(print()).andExpect(status().isOk())
|
||||
.andExpect(content().string("openfeign"));
|
||||
mvc.perform(get("/hello/proxy"))
|
||||
.andDo(print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string("openfeign"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotProxyAnyHeadersWithoutHeaderSet() throws Exception {
|
||||
mvc.perform(get("/headers/" + HttpHeaders.AUTHORIZATION + "/proxy")).andDo(print()).andExpect(status().isOk())
|
||||
.andExpect(content().string(""));
|
||||
mvc.perform(get("/headers/" + HttpHeaders.AUTHORIZATION + "/proxy"))
|
||||
.andDo(print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldProxyHeaderWhenHeaderSet() throws Exception {
|
||||
String authorization = UUID.randomUUID().toString();
|
||||
mvc.perform(get("/headers/" + HttpHeaders.AUTHORIZATION + "/proxy").header(HttpHeaders.AUTHORIZATION,
|
||||
authorization)).andDo(print()).andExpect(status().isOk()).andExpect(content().string(authorization));
|
||||
authorization))
|
||||
.andDo(print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(authorization));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldProxyHeaderWhenHeaderSetAndCleanRequestAttributesAfterReturn() throws Exception {
|
||||
shouldNotProxyAnyHeadersWithoutHeaderSet();
|
||||
Future<ServletRequestAttributes> future = asyncCircuitBreakerExecutor
|
||||
.submit(() -> (ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
|
||||
.submit(() -> (ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
|
||||
assertThat(future.get()).as("the RequestAttributes has been cleared").isNull();
|
||||
}
|
||||
|
||||
@@ -144,9 +151,10 @@ class AsyncCircuitBreakerTests {
|
||||
RequestInterceptor proxyHeaderRequestInterceptor() {
|
||||
return template -> {
|
||||
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
|
||||
.getRequestAttributes();
|
||||
String authorization = Objects.requireNonNull(requestAttributes).getRequest()
|
||||
.getHeader(HttpHeaders.AUTHORIZATION);
|
||||
.getRequestAttributes();
|
||||
String authorization = Objects.requireNonNull(requestAttributes)
|
||||
.getRequest()
|
||||
.getHeader(HttpHeaders.AUTHORIZATION);
|
||||
if (authorization != null) {
|
||||
// proxy authorization header
|
||||
template.header(HttpHeaders.AUTHORIZATION, authorization);
|
||||
|
||||
@@ -51,7 +51,7 @@ public class CircuitBreakerAutoConfigurationTests {
|
||||
when(target.type()).thenReturn(CircuitBreakerTests.TestClientWithFactory.class);
|
||||
assertThat(nameResolver.resolveCircuitBreakerName("foo", target,
|
||||
CircuitBreakerTests.TestClientWithFactory.class.getMethod("getHello")))
|
||||
.isEqualTo("TestClientWithFactory#getHello()");
|
||||
.isEqualTo("TestClientWithFactory#getHello()");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -73,7 +73,7 @@ public class CircuitBreakerAutoConfigurationTests {
|
||||
when(target.type()).thenReturn(CircuitBreakerTests.TestClientWithFactory.class);
|
||||
assertThat(nameResolver.resolveCircuitBreakerName("foo", target,
|
||||
CircuitBreakerTests.TestClientWithFactory.class.getMethod("getHello")))
|
||||
.isEqualTo("TestClientWithFactorygetHello");
|
||||
.isEqualTo("TestClientWithFactorygetHello");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ class CircuitBreakerTests {
|
||||
@Test
|
||||
void testRuntimeExceptionUnwrapped() {
|
||||
assertThatExceptionOfType(UnsupportedOperationException.class)
|
||||
.isThrownBy(() -> exceptionClient.getRuntimeException());
|
||||
.isThrownBy(() -> exceptionClient.getRuntimeException());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -46,41 +46,43 @@ class FallbackSupportFactoryBeanTests {
|
||||
private static final String ORIGINAL_FALLBACK_MESSAGE = "OriginalFeign fallback message";
|
||||
|
||||
private final ApplicationContextRunner runner = new ApplicationContextRunner()
|
||||
.withBean(FactoryBeanFallbackFeignFallback.class).withBean(OriginalFeignFallback.class)
|
||||
.withConfiguration(AutoConfigurations.of(TestConfiguration.class, FeignAutoConfiguration.class))
|
||||
.withBean(CircuitBreakerFactory.class, () -> new CircuitBreakerFactory() {
|
||||
@Override
|
||||
public CircuitBreaker create(String id) {
|
||||
return new CircuitBreaker() {
|
||||
@Override
|
||||
public <T> T run(Supplier<T> toRun, Function<Throwable, T> fallback) {
|
||||
try {
|
||||
return toRun.get();
|
||||
}
|
||||
catch (Throwable t) {
|
||||
return fallback.apply(t);
|
||||
}
|
||||
.withBean(FactoryBeanFallbackFeignFallback.class)
|
||||
.withBean(OriginalFeignFallback.class)
|
||||
.withConfiguration(AutoConfigurations.of(TestConfiguration.class, FeignAutoConfiguration.class))
|
||||
.withBean(CircuitBreakerFactory.class, () -> new CircuitBreakerFactory() {
|
||||
@Override
|
||||
public CircuitBreaker create(String id) {
|
||||
return new CircuitBreaker() {
|
||||
@Override
|
||||
public <T> T run(Supplier<T> toRun, Function<Throwable, T> fallback) {
|
||||
try {
|
||||
return toRun.get();
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Throwable t) {
|
||||
return fallback.apply(t);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConfigBuilder configBuilder(String id) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
protected ConfigBuilder configBuilder(String id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureDefault(Function defaultConfiguration) {
|
||||
@Override
|
||||
public void configureDefault(Function defaultConfiguration) {
|
||||
|
||||
}
|
||||
}).withPropertyValues("spring.cloud.openfeign.circuitbreaker.enabled=true");
|
||||
}
|
||||
})
|
||||
.withPropertyValues("spring.cloud.openfeign.circuitbreaker.enabled=true");
|
||||
|
||||
@Test
|
||||
void shouldRunFallbackFromBeanOrFactoryBean() {
|
||||
runner.run(ctx -> {
|
||||
assertThat(ctx.getBean(OriginalFeign.class).get().equals(ORIGINAL_FALLBACK_MESSAGE)).isTrue();
|
||||
assertThat(ctx.getBean(FactoryBeanFallbackFeign.class).get().equals(FACTORY_BEAN_FALLBACK_MESSAGE))
|
||||
.isTrue();
|
||||
.isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -65,8 +65,10 @@ class ProtobufSpringEncoderTests {
|
||||
|
||||
// a protobuf object with some content
|
||||
private final org.springframework.cloud.openfeign.encoding.proto.Request request = org.springframework.cloud.openfeign.encoding.proto.Request
|
||||
.newBuilder().setId(1000000)
|
||||
.setMsg("Erlang/OTP 最初是爱立信为开发电信设备系统设计的编程语言平台," + "电信设备(路由器、接入网关、…)典型设计是通过背板连接主控板卡与多块业务板卡的分布式系统。").build();
|
||||
.newBuilder()
|
||||
.setId(1000000)
|
||||
.setMsg("Erlang/OTP 最初是爱立信为开发电信设备系统设计的编程语言平台," + "电信设备(路由器、接入网关、…)典型设计是通过背板连接主控板卡与多块业务板卡的分布式系统。")
|
||||
.build();
|
||||
|
||||
@Test
|
||||
void testProtobuf() throws IOException {
|
||||
@@ -79,7 +81,7 @@ class ProtobufSpringEncoderTests {
|
||||
|
||||
assertThat(request.toByteArray()).isEqualTo(bytes);
|
||||
org.springframework.cloud.openfeign.encoding.proto.Request copy = org.springframework.cloud.openfeign.encoding.proto.Request
|
||||
.parseFrom(bytes);
|
||||
.parseFrom(bytes);
|
||||
assertThat(copy).isEqualTo(request);
|
||||
}
|
||||
|
||||
@@ -98,7 +100,7 @@ class ProtobufSpringEncoderTests {
|
||||
assertThat(request.toByteArray().length).isNotEqualTo(bytes.length);
|
||||
try {
|
||||
org.springframework.cloud.openfeign.encoding.proto.Request copy = org.springframework.cloud.openfeign.encoding.proto.Request
|
||||
.parseFrom(bytes);
|
||||
.parseFrom(bytes);
|
||||
fail("Expected an InvalidProtocolBufferException to be thrown");
|
||||
}
|
||||
catch (InvalidProtocolBufferException e) {
|
||||
@@ -120,14 +122,16 @@ class ProtobufSpringEncoderTests {
|
||||
|
||||
private HttpEntity toApacheHttpEntity(RequestTemplate requestTemplate) throws IOException {
|
||||
final List<ClassicHttpRequest> request = new ArrayList<>(1);
|
||||
BDDMockito.given(httpClient.execute(ArgumentMatchers.any(), ArgumentMatchers.any(),
|
||||
ArgumentMatchers.any(HttpContext.class))).will((Answer<HttpResponse>) invocationOnMock -> {
|
||||
request.add((ClassicHttpRequest) invocationOnMock.getArguments()[1]);
|
||||
try (ClassicHttpResponse response = new BasicClassicHttpResponse(200)) {
|
||||
response.setVersion(new ProtocolVersion("http", 1, 1));
|
||||
return response;
|
||||
}
|
||||
});
|
||||
BDDMockito
|
||||
.given(httpClient.execute(ArgumentMatchers.any(), ArgumentMatchers.any(),
|
||||
ArgumentMatchers.any(HttpContext.class)))
|
||||
.will((Answer<HttpResponse>) invocationOnMock -> {
|
||||
request.add((ClassicHttpRequest) invocationOnMock.getArguments()[1]);
|
||||
try (ClassicHttpResponse response = new BasicClassicHttpResponse(200)) {
|
||||
response.setVersion(new ProtocolVersion("http", 1, 1));
|
||||
return response;
|
||||
}
|
||||
});
|
||||
new ApacheHttp5Client(httpClient).execute(requestTemplate.resolve(new HashMap<>()).request(),
|
||||
new feign.Request.Options());
|
||||
ClassicHttpRequest httpUriRequest = request.get(0);
|
||||
|
||||
@@ -189,7 +189,7 @@ public final class Request extends com.google.protobuf.GeneratedMessageV3 implem
|
||||
|
||||
protected FieldAccessorTable internalGetFieldAccessorTable() {
|
||||
return org.springframework.cloud.openfeign.encoding.proto.ProtobufTest.internal_static_Request_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(Request.class, Request.Builder.class);
|
||||
.ensureFieldAccessorsInitialized(Request.class, Request.Builder.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -352,7 +352,7 @@ public final class Request extends com.google.protobuf.GeneratedMessageV3 implem
|
||||
|
||||
protected FieldAccessorTable internalGetFieldAccessorTable() {
|
||||
return org.springframework.cloud.openfeign.encoding.proto.ProtobufTest.internal_static_Request_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(Request.class, Request.Builder.class);
|
||||
.ensureFieldAccessorsInitialized(Request.class, Request.Builder.class);
|
||||
}
|
||||
|
||||
private void maybeForceBuilderInitialization() {
|
||||
|
||||
@@ -42,10 +42,10 @@ class FeignHalAutoConfigurationContextTests {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
contextRunner = new WebApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class,
|
||||
HttpMessageConvertersAutoConfiguration.class, HypermediaAutoConfiguration.class,
|
||||
RepositoryRestMvcAutoConfiguration.class, FeignHalAutoConfiguration.class))
|
||||
.withPropertyValues("debug=true");
|
||||
.withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class,
|
||||
HttpMessageConvertersAutoConfiguration.class, HypermediaAutoConfiguration.class,
|
||||
RepositoryRestMvcAutoConfiguration.class, FeignHalAutoConfiguration.class))
|
||||
.withPropertyValues("debug=true");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -53,14 +53,14 @@ class FeignHalAutoConfigurationContextTests {
|
||||
FilteredClassLoader filteredClassLoader = new FilteredClassLoader(RepositoryRestMvcConfiguration.class,
|
||||
WebConverters.class);
|
||||
contextRunner.withClassLoader(filteredClassLoader)
|
||||
.run(context -> assertThat(context).doesNotHaveBean("webConvertersCustomizer"));
|
||||
.run(context -> assertThat(context).doesNotHaveBean("webConvertersCustomizer"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldLoadWebConvertersCustomizer() {
|
||||
FilteredClassLoader filteredClassLoader = new FilteredClassLoader(RepositoryRestMvcConfiguration.class);
|
||||
contextRunner.withClassLoader(filteredClassLoader)
|
||||
.run(context -> assertThat(context).hasBean("webConvertersCustomizer"));
|
||||
.run(context -> assertThat(context).hasBean("webConvertersCustomizer"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -58,8 +58,8 @@ class FeignClientValidationTests {
|
||||
@Test
|
||||
void testNotLegalHostname() {
|
||||
assertThatExceptionOfType(IllegalStateException.class)
|
||||
.isThrownBy(() -> new AnnotationConfigApplicationContext(BadHostnameConfiguration.class))
|
||||
.withMessage("Service id not legal hostname (foo_bar)");
|
||||
.isThrownBy(() -> new AnnotationConfigApplicationContext(BadHostnameConfiguration.class))
|
||||
.withMessage("Service id not legal hostname (foo_bar)");
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
|
||||
@@ -108,8 +108,8 @@ class FeignBlockingLoadBalancerClientTests {
|
||||
Request request = testRequest("");
|
||||
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> feignBlockingLoadBalancerClient.execute(request, new Request.Options()))
|
||||
.withMessage("Request URI does not contain a valid hostname: http:///path");
|
||||
.isThrownBy(() -> feignBlockingLoadBalancerClient.execute(request, new Request.Options()))
|
||||
.withMessage("Request URI does not contain a valid hostname: http:///path");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -130,7 +130,7 @@ class FeignBlockingLoadBalancerClientTests {
|
||||
ServiceInstance serviceInstance = new DefaultServiceInstance("test-1", "test", "test-host", 8888, false);
|
||||
when(loadBalancerClient.choose(eq("test"), any())).thenReturn(serviceInstance);
|
||||
when(loadBalancerClient.reconstructURI(serviceInstance, URI.create("http://test/path")))
|
||||
.thenReturn(URI.create(url));
|
||||
.thenReturn(URI.create(url));
|
||||
|
||||
feignBlockingLoadBalancerClient.execute(request, options);
|
||||
|
||||
@@ -156,30 +156,30 @@ class FeignBlockingLoadBalancerClientTests {
|
||||
ServiceInstance serviceInstance = new DefaultServiceInstance("test-1", "test", "test-host", 8888, false);
|
||||
when(loadBalancerClient.choose(eq("test"), any())).thenReturn(serviceInstance);
|
||||
when(loadBalancerClient.reconstructURI(serviceInstance, URI.create("http://test/path")))
|
||||
.thenReturn(URI.create(url));
|
||||
.thenReturn(URI.create(url));
|
||||
String callbackTestHint = "callbackTestHint";
|
||||
loadBalancerProperties.getHint().put("test", callbackTestHint);
|
||||
Map<String, LoadBalancerLifecycle> loadBalancerLifecycleBeans = new HashMap<>();
|
||||
loadBalancerLifecycleBeans.put("loadBalancerLifecycle", new TestLoadBalancerLifecycle());
|
||||
loadBalancerLifecycleBeans.put("anotherLoadBalancerLifecycle", new AnotherLoadBalancerLifecycle());
|
||||
when(loadBalancerClientFactory.getInstances("test", LoadBalancerLifecycle.class))
|
||||
.thenReturn(loadBalancerLifecycleBeans);
|
||||
.thenReturn(loadBalancerLifecycleBeans);
|
||||
|
||||
feignBlockingLoadBalancerClient.execute(request, options);
|
||||
|
||||
Collection<org.springframework.cloud.client.loadbalancer.Request<RequestDataContext>> lifecycleLogRequests = ((TestLoadBalancerLifecycle) loadBalancerLifecycleBeans
|
||||
.get("loadBalancerLifecycle")).getStartLog().values();
|
||||
.get("loadBalancerLifecycle")).getStartLog().values();
|
||||
Collection<org.springframework.cloud.client.loadbalancer.Request<RequestDataContext>> lifecycleLogStartedRequests = ((TestLoadBalancerLifecycle) loadBalancerLifecycleBeans
|
||||
.get("loadBalancerLifecycle")).getStartRequestLog().values();
|
||||
.get("loadBalancerLifecycle")).getStartRequestLog().values();
|
||||
Collection<CompletionContext<ResponseData, ServiceInstance, RequestDataContext>> anotherLifecycleLogRequests = ((AnotherLoadBalancerLifecycle) loadBalancerLifecycleBeans
|
||||
.get("anotherLoadBalancerLifecycle")).getCompleteLog().values();
|
||||
.get("anotherLoadBalancerLifecycle")).getCompleteLog().values();
|
||||
assertThat(lifecycleLogRequests).extracting(lbRequest -> lbRequest.getContext().getHint())
|
||||
.contains(callbackTestHint);
|
||||
.contains(callbackTestHint);
|
||||
assertThat(lifecycleLogStartedRequests).extracting(lbRequest -> lbRequest.getContext().getHint())
|
||||
.contains(callbackTestHint);
|
||||
.contains(callbackTestHint);
|
||||
assertThat(anotherLifecycleLogRequests)
|
||||
.extracting(completionContext -> completionContext.getClientResponse().getHttpStatus())
|
||||
.contains(HttpStatus.OK);
|
||||
.extracting(completionContext -> completionContext.getClientResponse().getHttpStatus())
|
||||
.contains(HttpStatus.OK);
|
||||
}
|
||||
|
||||
private String read(Response response) throws IOException {
|
||||
|
||||
@@ -58,7 +58,7 @@ class FeignLoadBalancerAutoConfigurationTests {
|
||||
"spring.cloud.openfeign.httpclient.okhttp.read-timeout=9s");
|
||||
assertThatOneBeanPresent(context, BlockingLoadBalancerClient.class);
|
||||
Map<String, FeignBlockingLoadBalancerClient> beans = context
|
||||
.getBeansOfType(FeignBlockingLoadBalancerClient.class);
|
||||
.getBeansOfType(FeignBlockingLoadBalancerClient.class);
|
||||
assertThat(beans).as("Missing bean of type %s", OkHttpClient.class).hasSize(1);
|
||||
Client client = beans.get("feignClient").getDelegate();
|
||||
assertThat(client).isInstanceOf(OkHttpClient.class);
|
||||
@@ -74,7 +74,7 @@ class FeignLoadBalancerAutoConfigurationTests {
|
||||
"spring.cloud.openfeign.http2client.enabled=true", "spring.cloud.loadbalancer.retry.enabled=false");
|
||||
assertThatOneBeanPresent(context, BlockingLoadBalancerClient.class);
|
||||
Map<String, FeignBlockingLoadBalancerClient> beans = context
|
||||
.getBeansOfType(FeignBlockingLoadBalancerClient.class);
|
||||
.getBeansOfType(FeignBlockingLoadBalancerClient.class);
|
||||
assertThat(beans).as("Missing bean of type %s", Http2Client.class).hasSize(1);
|
||||
Client client = beans.get("feignClient").getDelegate();
|
||||
assertThat(client).isInstanceOf(Http2Client.class);
|
||||
@@ -130,10 +130,11 @@ class FeignLoadBalancerAutoConfigurationTests {
|
||||
}
|
||||
|
||||
private ConfigurableApplicationContext initContext(String... properties) {
|
||||
return new SpringApplicationBuilder().web(WebApplicationType.NONE).properties(properties)
|
||||
.sources(LoadBalancerAutoConfiguration.class, BlockingLoadBalancerClientAutoConfiguration.class,
|
||||
FeignLoadBalancerAutoConfiguration.class, FeignAutoConfiguration.class)
|
||||
.run();
|
||||
return new SpringApplicationBuilder().web(WebApplicationType.NONE)
|
||||
.properties(properties)
|
||||
.sources(LoadBalancerAutoConfiguration.class, BlockingLoadBalancerClientAutoConfiguration.class,
|
||||
FeignLoadBalancerAutoConfiguration.class, FeignAutoConfiguration.class)
|
||||
.run();
|
||||
}
|
||||
|
||||
private void assertThatOneBeanPresent(ConfigurableApplicationContext context, Class<?> beanClass) {
|
||||
@@ -143,17 +144,17 @@ class FeignLoadBalancerAutoConfigurationTests {
|
||||
|
||||
private void assertLoadBalanced(ConfigurableApplicationContext context, Class delegateClass) {
|
||||
Map<String, FeignBlockingLoadBalancerClient> beans = context
|
||||
.getBeansOfType(FeignBlockingLoadBalancerClient.class);
|
||||
.getBeansOfType(FeignBlockingLoadBalancerClient.class);
|
||||
assertThat(beans).as("Missing bean of type %s", delegateClass).hasSize(1);
|
||||
assertThat(beans.get("feignClient").getDelegate()).isInstanceOf(delegateClass);
|
||||
}
|
||||
|
||||
private void assertLoadBalancedWithRetries(ConfigurableApplicationContext context, Class delegateClass) {
|
||||
Map<String, RetryableFeignBlockingLoadBalancerClient> retryableBeans = context
|
||||
.getBeansOfType(RetryableFeignBlockingLoadBalancerClient.class);
|
||||
.getBeansOfType(RetryableFeignBlockingLoadBalancerClient.class);
|
||||
assertThat(retryableBeans).hasSize(1);
|
||||
Map<String, FeignBlockingLoadBalancerClient> beans = context
|
||||
.getBeansOfType(FeignBlockingLoadBalancerClient.class);
|
||||
.getBeansOfType(FeignBlockingLoadBalancerClient.class);
|
||||
assertThat(beans).isEmpty();
|
||||
assertThat(retryableBeans.get("feignRetryClient").getDelegate()).isInstanceOf(delegateClass);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ class RetryableFeignBlockingLoadBalancerClientTests {
|
||||
void setUp() {
|
||||
when(loadBalancerClientFactory.getProperties(any(String.class))).thenReturn(properties);
|
||||
when(retryFactory.createRetryPolicy(any(), eq(loadBalancerClient)))
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
when(loadBalancerClient.choose(eq("test"), any())).thenReturn(serviceInstance);
|
||||
}
|
||||
|
||||
@@ -114,17 +114,17 @@ class RetryableFeignBlockingLoadBalancerClientTests {
|
||||
Response response = testResponse(200);
|
||||
when(delegate.execute(any(), any())).thenReturn(response);
|
||||
when(retryFactory.createRetryPolicy(any(), eq(loadBalancerClient)))
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
when(loadBalancerClient.reconstructURI(serviceInstance, URI.create("http://test/path")))
|
||||
.thenReturn(URI.create("http://testhost:80/path"));
|
||||
.thenReturn(URI.create("http://testhost:80/path"));
|
||||
|
||||
feignBlockingLoadBalancerClient.execute(request, new Request.Options());
|
||||
|
||||
verify(loadBalancerClient).choose(eq("test"), any());
|
||||
verify(loadBalancerClient).reconstructURI(serviceInstance, URI.create("http://test/path"));
|
||||
|
||||
verify(delegate).execute(
|
||||
argThat((Request actualRequest) -> actualRequest.url().equals("http://testhost:80/path")), any());
|
||||
verify(delegate)
|
||||
.execute(argThat((Request actualRequest) -> actualRequest.url().equals("http://testhost:80/path")), any());
|
||||
}
|
||||
|
||||
private Response testResponse(int status) {
|
||||
@@ -145,7 +145,7 @@ class RetryableFeignBlockingLoadBalancerClientTests {
|
||||
when(loadBalancerClient.choose(eq("test"), any())).thenReturn(null);
|
||||
when(delegate.execute(any(), any())).thenReturn(response);
|
||||
when(retryFactory.createRetryPolicy(any(), eq(loadBalancerClient)))
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
|
||||
feignBlockingLoadBalancerClient.execute(request, new Request.Options());
|
||||
|
||||
@@ -159,9 +159,9 @@ class RetryableFeignBlockingLoadBalancerClientTests {
|
||||
Response response = testResponse(503);
|
||||
when(delegate.execute(any(), any())).thenReturn(response);
|
||||
when(retryFactory.createRetryPolicy(any(), eq(loadBalancerClient)))
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
when(loadBalancerClient.reconstructURI(serviceInstance, URI.create("http://test/path")))
|
||||
.thenReturn(URI.create("http://testhost:80/path"));
|
||||
.thenReturn(URI.create("http://testhost:80/path"));
|
||||
|
||||
feignBlockingLoadBalancerClient.execute(request, new Request.Options());
|
||||
|
||||
@@ -179,9 +179,9 @@ class RetryableFeignBlockingLoadBalancerClientTests {
|
||||
Response response = testResponse(503);
|
||||
when(delegate.execute(any(), any())).thenReturn(response);
|
||||
when(retryFactory.createRetryPolicy(any(), eq(loadBalancerClient)))
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
when(loadBalancerClient.reconstructURI(serviceInstance, URI.create("http://test/path")))
|
||||
.thenReturn(URI.create("http://testhost:80/path"));
|
||||
.thenReturn(URI.create("http://testhost:80/path"));
|
||||
|
||||
feignBlockingLoadBalancerClient.execute(request, new Request.Options());
|
||||
|
||||
@@ -199,9 +199,9 @@ class RetryableFeignBlockingLoadBalancerClientTests {
|
||||
Response response = testResponse(503);
|
||||
when(delegate.execute(any(), any())).thenReturn(response);
|
||||
when(retryFactory.createRetryPolicy(any(), eq(loadBalancerClient)))
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
when(loadBalancerClient.reconstructURI(serviceInstance, URI.create("http://test/path")))
|
||||
.thenReturn(URI.create("http://testhost:80/path"));
|
||||
.thenReturn(URI.create("http://testhost:80/path"));
|
||||
|
||||
feignBlockingLoadBalancerClient.execute(request, new Request.Options());
|
||||
|
||||
@@ -216,10 +216,10 @@ class RetryableFeignBlockingLoadBalancerClientTests {
|
||||
Request request = testRequest();
|
||||
when(delegate.execute(any(), any())).thenThrow(new IOException());
|
||||
when(retryFactory.createRetryPolicy(any(), eq(loadBalancerClient)))
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
|
||||
assertThatThrownBy(() -> feignBlockingLoadBalancerClient.execute(request, new Request.Options()))
|
||||
.isInstanceOf(IOException.class);
|
||||
.isInstanceOf(IOException.class);
|
||||
|
||||
verify(delegate, times(1)).execute(any(), any());
|
||||
}
|
||||
@@ -230,9 +230,9 @@ class RetryableFeignBlockingLoadBalancerClientTests {
|
||||
Request request = testRequest();
|
||||
when(delegate.execute(any(), any())).thenReturn(testResponse(503, "foo"), testResponse(503, "foo"));
|
||||
when(retryFactory.createRetryPolicy(any(), eq(loadBalancerClient)))
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
when(loadBalancerClient.reconstructURI(serviceInstance, URI.create("http://test/path")))
|
||||
.thenReturn(URI.create("http://testhost:80/path"));
|
||||
.thenReturn(URI.create("http://testhost:80/path"));
|
||||
|
||||
Response response = feignBlockingLoadBalancerClient.execute(request, new Request.Options());
|
||||
|
||||
@@ -248,11 +248,11 @@ class RetryableFeignBlockingLoadBalancerClientTests {
|
||||
ServiceInstance serviceInstance = new DefaultServiceInstance("test-1", "test", "test-host", 8888, false);
|
||||
when(loadBalancerClient.choose(eq("test"), any())).thenReturn(serviceInstance);
|
||||
when(loadBalancerClient.reconstructURI(serviceInstance, URI.create("http://test/path")))
|
||||
.thenReturn(URI.create(url));
|
||||
.thenReturn(URI.create(url));
|
||||
Response response = testResponse(200);
|
||||
when(delegate.execute(any(), any())).thenReturn(response);
|
||||
when(retryFactory.createRetryPolicy(any(), eq(loadBalancerClient)))
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
|
||||
|
||||
feignBlockingLoadBalancerClient.execute(request, options);
|
||||
|
||||
@@ -277,7 +277,7 @@ class RetryableFeignBlockingLoadBalancerClientTests {
|
||||
ServiceInstance serviceInstance = new DefaultServiceInstance("test-1", "test", "test-host", 8888, false);
|
||||
when(loadBalancerClient.choose(eq("test"), any())).thenReturn(serviceInstance);
|
||||
when(loadBalancerClient.reconstructURI(serviceInstance, URI.create("http://test/path")))
|
||||
.thenReturn(URI.create(url));
|
||||
.thenReturn(URI.create(url));
|
||||
Response response = testResponse(200);
|
||||
when(delegate.execute(any(), any())).thenReturn(response);
|
||||
String callbackTestHint = "callbackTestHint";
|
||||
@@ -286,23 +286,23 @@ class RetryableFeignBlockingLoadBalancerClientTests {
|
||||
loadBalancerLifecycleBeans.put("loadBalancerLifecycle", new TestLoadBalancerLifecycle());
|
||||
loadBalancerLifecycleBeans.put("anotherLoadBalancerLifecycle", new AnotherLoadBalancerLifecycle());
|
||||
when(loadBalancerClientFactory.getInstances("test", LoadBalancerLifecycle.class))
|
||||
.thenReturn(loadBalancerLifecycleBeans);
|
||||
.thenReturn(loadBalancerLifecycleBeans);
|
||||
|
||||
feignBlockingLoadBalancerClient.execute(request, options);
|
||||
|
||||
Collection<org.springframework.cloud.client.loadbalancer.Request<RetryableRequestContext>> lifecycleLogRequests = ((TestLoadBalancerLifecycle) loadBalancerLifecycleBeans
|
||||
.get("loadBalancerLifecycle")).getStartLog().values();
|
||||
.get("loadBalancerLifecycle")).getStartLog().values();
|
||||
Collection<org.springframework.cloud.client.loadbalancer.Request<RetryableRequestContext>> lifecycleLogStartedRequests = ((TestLoadBalancerLifecycle) loadBalancerLifecycleBeans
|
||||
.get("loadBalancerLifecycle")).getStartRequestLog().values();
|
||||
.get("loadBalancerLifecycle")).getStartRequestLog().values();
|
||||
Collection<CompletionContext<ResponseData, ServiceInstance, RetryableRequestContext>> anotherLifecycleLogRequests = ((AnotherLoadBalancerLifecycle) loadBalancerLifecycleBeans
|
||||
.get("anotherLoadBalancerLifecycle")).getCompleteLog().values();
|
||||
.get("anotherLoadBalancerLifecycle")).getCompleteLog().values();
|
||||
assertThat(lifecycleLogRequests).extracting(lbRequest -> lbRequest.getContext().getHint())
|
||||
.contains(callbackTestHint);
|
||||
.contains(callbackTestHint);
|
||||
assertThat(lifecycleLogStartedRequests).extracting(lbRequest -> lbRequest.getContext().getHint())
|
||||
.contains(callbackTestHint);
|
||||
.contains(callbackTestHint);
|
||||
assertThat(anotherLifecycleLogRequests)
|
||||
.extracting(completionContext -> completionContext.getClientResponse().getHttpStatus())
|
||||
.contains(HttpStatus.OK);
|
||||
.extracting(completionContext -> completionContext.getClientResponse().getHttpStatus())
|
||||
.contains(HttpStatus.OK);
|
||||
}
|
||||
|
||||
private Request testRequest() {
|
||||
|
||||
@@ -70,16 +70,16 @@ class OAuth2AccessTokenInterceptorTests {
|
||||
when(mockOAuth2AuthorizedClientManager.authorize(any())).thenReturn(null);
|
||||
|
||||
assertThatExceptionOfType(IllegalStateException.class)
|
||||
.isThrownBy(() -> oAuth2AccessTokenInterceptor.apply(requestTemplate))
|
||||
.withMessage("OAuth2 token has not been successfully acquired.");
|
||||
.isThrownBy(() -> oAuth2AccessTokenInterceptor.apply(requestTemplate))
|
||||
.withMessage("OAuth2 token has not been successfully acquired.");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldAcquireValidToken() {
|
||||
oAuth2AccessTokenInterceptor = new OAuth2AccessTokenInterceptor(mockOAuth2AuthorizedClientManager);
|
||||
when(mockOAuth2AuthorizedClientManager.authorize(
|
||||
argThat((OAuth2AuthorizeRequest request) -> ("test").equals(request.getClientRegistrationId()))))
|
||||
.thenReturn(validTokenOAuth2AuthorizedClient());
|
||||
when(mockOAuth2AuthorizedClientManager
|
||||
.authorize(argThat((OAuth2AuthorizeRequest request) -> ("test").equals(request.getClientRegistrationId()))))
|
||||
.thenReturn(validTokenOAuth2AuthorizedClient());
|
||||
|
||||
oAuth2AccessTokenInterceptor.apply(requestTemplate);
|
||||
|
||||
@@ -88,9 +88,9 @@ class OAuth2AccessTokenInterceptorTests {
|
||||
|
||||
@Test
|
||||
void shouldAcquireValidTokenFromServiceId() {
|
||||
when(mockOAuth2AuthorizedClientManager.authorize(
|
||||
argThat((OAuth2AuthorizeRequest request) -> ("test").equals(request.getClientRegistrationId()))))
|
||||
.thenReturn(validTokenOAuth2AuthorizedClient());
|
||||
when(mockOAuth2AuthorizedClientManager
|
||||
.authorize(argThat((OAuth2AuthorizeRequest request) -> ("test").equals(request.getClientRegistrationId()))))
|
||||
.thenReturn(validTokenOAuth2AuthorizedClient());
|
||||
oAuth2AccessTokenInterceptor = new OAuth2AccessTokenInterceptor(mockOAuth2AuthorizedClientManager);
|
||||
|
||||
oAuth2AccessTokenInterceptor.apply(requestTemplate);
|
||||
@@ -103,8 +103,9 @@ class OAuth2AccessTokenInterceptorTests {
|
||||
oAuth2AccessTokenInterceptor = new OAuth2AccessTokenInterceptor(DEFAULT_CLIENT_REGISTRATION_ID,
|
||||
mockOAuth2AuthorizedClientManager);
|
||||
when(mockOAuth2AuthorizedClientManager
|
||||
.authorize(argThat((OAuth2AuthorizeRequest request) -> (DEFAULT_CLIENT_REGISTRATION_ID)
|
||||
.equals(request.getClientRegistrationId())))).thenReturn(validTokenOAuth2AuthorizedClient());
|
||||
.authorize(argThat((OAuth2AuthorizeRequest request) -> (DEFAULT_CLIENT_REGISTRATION_ID)
|
||||
.equals(request.getClientRegistrationId()))))
|
||||
.thenReturn(validTokenOAuth2AuthorizedClient());
|
||||
|
||||
oAuth2AccessTokenInterceptor.apply(requestTemplate);
|
||||
|
||||
@@ -121,8 +122,11 @@ class OAuth2AccessTokenInterceptorTests {
|
||||
}
|
||||
|
||||
private ClientRegistration defaultClientRegistration() {
|
||||
return ClientRegistration.withRegistrationId(DEFAULT_CLIENT_REGISTRATION_ID).clientId("clientId")
|
||||
.tokenUri("mock token uri").authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS).build();
|
||||
return ClientRegistration.withRegistrationId(DEFAULT_CLIENT_REGISTRATION_ID)
|
||||
.clientId("clientId")
|
||||
.tokenUri("mock token uri")
|
||||
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -58,8 +58,13 @@ public class AbstractSpringMvcContractIntegrationTests {
|
||||
}
|
||||
|
||||
protected String getUrlQueryParam(Response response) {
|
||||
return response.request().requestTemplate().queries().get("url").stream().findFirst()
|
||||
.orElseThrow(IllegalStateException::new);
|
||||
return response.request()
|
||||
.requestTemplate()
|
||||
.queries()
|
||||
.get("url")
|
||||
.stream()
|
||||
.findFirst()
|
||||
.orElseThrow(IllegalStateException::new);
|
||||
}
|
||||
|
||||
@FeignClient(name = "test", url = "http://localhost:${server.port}/",
|
||||
|
||||
@@ -58,42 +58,42 @@ class FeignHttpClientPropertiesTests {
|
||||
void testDefaults() {
|
||||
setupContext();
|
||||
assertThat(getProperties().getConnectionTimeout())
|
||||
.isEqualTo(FeignHttpClientProperties.DEFAULT_CONNECTION_TIMEOUT);
|
||||
.isEqualTo(FeignHttpClientProperties.DEFAULT_CONNECTION_TIMEOUT);
|
||||
assertThat(getProperties().getMaxConnections()).isEqualTo(FeignHttpClientProperties.DEFAULT_MAX_CONNECTIONS);
|
||||
assertThat(getProperties().getMaxConnectionsPerRoute())
|
||||
.isEqualTo(FeignHttpClientProperties.DEFAULT_MAX_CONNECTIONS_PER_ROUTE);
|
||||
.isEqualTo(FeignHttpClientProperties.DEFAULT_MAX_CONNECTIONS_PER_ROUTE);
|
||||
assertThat(getProperties().getTimeToLive()).isEqualTo(FeignHttpClientProperties.DEFAULT_TIME_TO_LIVE);
|
||||
assertThat(getProperties().isDisableSslValidation())
|
||||
.isEqualTo(FeignHttpClientProperties.DEFAULT_DISABLE_SSL_VALIDATION);
|
||||
.isEqualTo(FeignHttpClientProperties.DEFAULT_DISABLE_SSL_VALIDATION);
|
||||
assertThat(getProperties().isFollowRedirects()).isEqualTo(FeignHttpClientProperties.DEFAULT_FOLLOW_REDIRECTS);
|
||||
assertThat(getProperties().getHc5().getPoolConcurrencyPolicy()).isEqualTo(PoolConcurrencyPolicy.STRICT);
|
||||
assertThat(getProperties().getHc5().getPoolReusePolicy()).isEqualTo(PoolReusePolicy.FIFO);
|
||||
assertThat(getProperties().getHc5().getSocketTimeout()).isEqualTo(DEFAULT_SOCKET_TIMEOUT);
|
||||
assertThat(getProperties().getHc5().getSocketTimeoutUnit()).isEqualTo(DEFAULT_SOCKET_TIMEOUT_UNIT);
|
||||
assertThat(getProperties().getHc5().getConnectionRequestTimeout())
|
||||
.isEqualTo(DEFAULT_CONNECTION_REQUEST_TIMEOUT);
|
||||
.isEqualTo(DEFAULT_CONNECTION_REQUEST_TIMEOUT);
|
||||
assertThat(getProperties().getHc5().getConnectionRequestTimeoutUnit())
|
||||
.isEqualTo(DEFAULT_CONNECTION_REQUEST_TIMEOUT_UNIT);
|
||||
.isEqualTo(DEFAULT_CONNECTION_REQUEST_TIMEOUT_UNIT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCustomization() {
|
||||
TestPropertyValues
|
||||
.of("spring.cloud.openfeign.httpclient.maxConnections=2",
|
||||
"spring.cloud.openfeign.httpclient.connectionTimeout=2",
|
||||
"spring.cloud.openfeign.httpclient.maxConnectionsPerRoute=2",
|
||||
"spring.cloud.openfeign.httpclient.timeToLive=2",
|
||||
"spring.cloud.openfeign.httpclient.disableSslValidation=true",
|
||||
"spring.cloud.openfeign.httpclient.followRedirects=false",
|
||||
"spring.cloud.openfeign.httpclient.disableSslValidation=true",
|
||||
"spring.cloud.openfeign.httpclient.followRedirects=false",
|
||||
"spring.cloud.openfeign.httpclient.hc5.poolConcurrencyPolicy=lax",
|
||||
"spring.cloud.openfeign.httpclient.hc5.poolReusePolicy=lifo",
|
||||
"spring.cloud.openfeign.httpclient.hc5.socketTimeout=200",
|
||||
"spring.cloud.openfeign.httpclient.hc5.socketTimeoutUnit=milliseconds",
|
||||
"spring.cloud.openfeign.httpclient.hc5.connectionRequestTimeout=200",
|
||||
"spring.cloud.openfeign.httpclient.hc5.connectionRequestTimeoutUnit=milliseconds")
|
||||
.applyTo(this.context);
|
||||
.of("spring.cloud.openfeign.httpclient.maxConnections=2",
|
||||
"spring.cloud.openfeign.httpclient.connectionTimeout=2",
|
||||
"spring.cloud.openfeign.httpclient.maxConnectionsPerRoute=2",
|
||||
"spring.cloud.openfeign.httpclient.timeToLive=2",
|
||||
"spring.cloud.openfeign.httpclient.disableSslValidation=true",
|
||||
"spring.cloud.openfeign.httpclient.followRedirects=false",
|
||||
"spring.cloud.openfeign.httpclient.disableSslValidation=true",
|
||||
"spring.cloud.openfeign.httpclient.followRedirects=false",
|
||||
"spring.cloud.openfeign.httpclient.hc5.poolConcurrencyPolicy=lax",
|
||||
"spring.cloud.openfeign.httpclient.hc5.poolReusePolicy=lifo",
|
||||
"spring.cloud.openfeign.httpclient.hc5.socketTimeout=200",
|
||||
"spring.cloud.openfeign.httpclient.hc5.socketTimeoutUnit=milliseconds",
|
||||
"spring.cloud.openfeign.httpclient.hc5.connectionRequestTimeout=200",
|
||||
"spring.cloud.openfeign.httpclient.hc5.connectionRequestTimeoutUnit=milliseconds")
|
||||
.applyTo(this.context);
|
||||
setupContext();
|
||||
assertThat(getProperties().getMaxConnections()).isEqualTo(2);
|
||||
assertThat(getProperties().getConnectionTimeout()).isEqualTo(2);
|
||||
|
||||
@@ -82,7 +82,7 @@ class PageJacksonModuleTests {
|
||||
assertThat(result.getContent()).hasSize(10);
|
||||
assertThat(result.getPageable().getPageNumber()).isEqualTo(0);
|
||||
assertThat(result.getPageable().getSort().getOrderFor("lastName").getDirection())
|
||||
.isEqualTo(Sort.Direction.DESC);
|
||||
.isEqualTo(Sort.Direction.DESC);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -143,7 +143,7 @@ class SpringEncoderTests {
|
||||
encoder.encode("hi".getBytes(), null, request);
|
||||
|
||||
assertThat(((List) request.headers().get(CONTENT_TYPE)).get(0)).as("Request Content-Type is not octet-stream")
|
||||
.isEqualTo(APPLICATION_OCTET_STREAM_VALUE);
|
||||
.isEqualTo(APPLICATION_OCTET_STREAM_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -155,7 +155,7 @@ class SpringEncoderTests {
|
||||
MultipartFile multipartFile = new MockMultipartFile("test_multipart_file", "hi".getBytes());
|
||||
|
||||
Assertions.assertThatExceptionOfType(EncodeException.class)
|
||||
.isThrownBy(() -> encoder.encode(multipartFile, MultipartFile.class, request));
|
||||
.isThrownBy(() -> encoder.encode(multipartFile, MultipartFile.class, request));
|
||||
}
|
||||
|
||||
// gh-105, gh-107
|
||||
@@ -171,14 +171,15 @@ class SpringEncoderTests {
|
||||
encoder.encode(multipartFile, MultipartFile.class, request);
|
||||
|
||||
assertThat((String) ((List) request.headers().get(CONTENT_TYPE)).get(0))
|
||||
.as("Request Content-Type is not multipart/form-data")
|
||||
.contains("multipart/form-data; charset=UTF-8; boundary=");
|
||||
.as("Request Content-Type is not multipart/form-data")
|
||||
.contains("multipart/form-data; charset=UTF-8; boundary=");
|
||||
assertThat(request.headers().get(CONTENT_TYPE).size()).as("There is more than one Content-Type request header")
|
||||
.isEqualTo(1);
|
||||
.isEqualTo(1);
|
||||
assertThat(((List) request.headers().get(ACCEPT)).get(0)).as("Request Accept header is not multipart/form-data")
|
||||
.isEqualTo(MULTIPART_FORM_DATA_VALUE);
|
||||
.isEqualTo(MULTIPART_FORM_DATA_VALUE);
|
||||
assertThat(((List) request.headers().get(CONTENT_LENGTH)).get(0))
|
||||
.as("Request Content-Length is not equal to 186").isEqualTo("186");
|
||||
.as("Request Content-Length is not equal to 186")
|
||||
.isEqualTo("186");
|
||||
assertThat(new String(request.body())).as("Body content cannot be decoded").contains("hi");
|
||||
}
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ class SpringMvcContractTests {
|
||||
assertThat(data.template().url()).isEqualTo("/test/{id}");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
assertThat(data.template().decodeSlash()).isTrue();
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ class SpringMvcContractTests {
|
||||
assertThat(data.template().url()).isEqualTo("/test/{id}");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
assertThat(data.indexToName().get(0).iterator().next()).isEqualTo("id");
|
||||
}
|
||||
@@ -185,7 +185,7 @@ class SpringMvcContractTests {
|
||||
assertThat(data.template().url()).isEqualTo("/");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -196,7 +196,7 @@ class SpringMvcContractTests {
|
||||
assertThat(data.template().url()).isEqualTo("/?id=" + "{id}");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -207,7 +207,7 @@ class SpringMvcContractTests {
|
||||
assertThat(data.template().url()).isEqualTo("/test?name=" + "{name}");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -218,7 +218,7 @@ class SpringMvcContractTests {
|
||||
assertThat(data.template().url()).isEqualTo("/test/{id}");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
assertThat(data.indexToName().get(0).iterator().next()).isEqualTo("id");
|
||||
}
|
||||
@@ -268,7 +268,7 @@ class SpringMvcContractTests {
|
||||
assertThat(data.template().url()).isEqualTo("/");
|
||||
assertThat(data.template().method()).isEqualTo("POST");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
}
|
||||
|
||||
@@ -280,7 +280,7 @@ class SpringMvcContractTests {
|
||||
assertThat(data.template().url()).isEqualTo("/");
|
||||
assertThat(data.template().method()).isEqualTo("POST");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ class SpringMvcContractTests {
|
||||
assertThat(data.template().url()).isEqualTo("/test/{id}?amount=" + "{amount}");
|
||||
assertThat(data.template().method()).isEqualTo("PUT");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -332,7 +332,7 @@ class SpringMvcContractTests {
|
||||
assertThat(data.template().url()).isEqualTo("/test/{id}?amount=" + "{amount}");
|
||||
assertThat(data.template().method()).isEqualTo("PUT");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
assertThat(data.indexToName().get(0).iterator().next()).isEqualTo("Authorization");
|
||||
assertThat(data.indexToName().get(1).iterator().next()).isEqualTo("id");
|
||||
@@ -351,7 +351,7 @@ class SpringMvcContractTests {
|
||||
assertThat(data.template().url()).isEqualTo("/test2?amount=" + "{amount}");
|
||||
assertThat(data.template().method()).isEqualTo("PUT");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
assertThat(data.indexToName().get(0).iterator().next()).isEqualTo("Authorization");
|
||||
assertThat(data.indexToName().get(1).iterator().next()).isEqualTo("amount");
|
||||
@@ -403,7 +403,7 @@ class SpringMvcContractTests {
|
||||
assertThat(data.template().url()).isEqualTo("/");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -414,7 +414,7 @@ class SpringMvcContractTests {
|
||||
assertThat(data.template().url()).isEqualTo("/");
|
||||
assertThat(data.template().method()).isEqualTo("GET");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
assertThat(data.template().decodeSlash()).isTrue();
|
||||
}
|
||||
|
||||
@@ -557,7 +557,7 @@ class SpringMvcContractTests {
|
||||
assertThat(data.template().url()).isEqualTo("/testfallback/{id}?amount=" + "{amount}");
|
||||
assertThat(data.template().method()).isEqualTo("PUT");
|
||||
assertThat(data.template().headers().get("Accept").iterator().next())
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
assertThat(data.indexToName().get(0).iterator().next()).isEqualTo("Authorization");
|
||||
assertThat(data.indexToName().get(1).iterator().next()).isEqualTo("id");
|
||||
@@ -584,7 +584,7 @@ class SpringMvcContractTests {
|
||||
Method method = TestTemplate_HeaderMap.class.getDeclaredMethod("headerMapMoreThanOnce", MultiValueMap.class,
|
||||
MultiValueMap.class);
|
||||
assertThatExceptionOfType(IllegalStateException.class)
|
||||
.isThrownBy(() -> contract.parseAndValidateMetadata(method.getDeclaringClass(), method));
|
||||
.isThrownBy(() -> contract.parseAndValidateMetadata(method.getDeclaringClass(), method));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -616,7 +616,7 @@ class SpringMvcContractTests {
|
||||
Method method = TestTemplate_QueryMap.class.getDeclaredMethod("queryMapMoreThanOnce", MultiValueMap.class,
|
||||
MultiValueMap.class);
|
||||
assertThatExceptionOfType(IllegalStateException.class)
|
||||
.isThrownBy(() -> contract.parseAndValidateMetadata(method.getDeclaringClass(), method));
|
||||
.isThrownBy(() -> contract.parseAndValidateMetadata(method.getDeclaringClass(), method));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -688,7 +688,7 @@ class SpringMvcContractTests {
|
||||
|
||||
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
|
||||
assertThat(data.template().headers().get("cookie").iterator().next())
|
||||
.isEqualTo("cookie1={cookie1}; cookie2={cookie2}");
|
||||
.isEqualTo("cookie1={cookie1}; cookie2={cookie2}");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1002,8 +1002,13 @@ class SpringMvcContractTests {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("TestObject{").append("something='").append(something).append("', ")
|
||||
.append("number=").append(number).append("}").toString();
|
||||
return new StringBuilder("TestObject{").append("something='")
|
||||
.append(something)
|
||||
.append("', ")
|
||||
.append("number=")
|
||||
.append(number)
|
||||
.append("}")
|
||||
.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -555,7 +555,8 @@ class ValidFeignClientTests {
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(Application.class)
|
||||
.properties("spring.application.name=feignclienttest", "management.contextPath=/admin").run(args);
|
||||
.properties("spring.application.name=feignclienttest", "management.contextPath=/admin")
|
||||
.run(args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
Reference in New Issue
Block a user