Compare commits
12 Commits
main
...
aot-suppor
Author | SHA1 | Date |
---|---|---|
Olga Maciaszek-Sharma | fd1c364323 | 2 years ago |
Olga Maciaszek-Sharma | 0cde956b7e | 2 years ago |
Olga Maciaszek-Sharma | 8d8f82ad0c | 2 years ago |
Olga Maciaszek-Sharma | b10632f6b5 | 2 years ago |
Olga Maciaszek-Sharma | c44782d8b4 | 2 years ago |
Olga Maciaszek-Sharma | d501773120 | 2 years ago |
Olga Maciaszek-Sharma | ec64c62abb | 2 years ago |
Olga Maciaszek-Sharma | b7c43f02c1 | 2 years ago |
Olga Maciaszek-Sharma | 77ca6f9535 | 2 years ago |
Olga Maciaszek-Sharma | 6a833cd3db | 2 years ago |
Olga Maciaszek-Sharma | 577153a40c | 2 years ago |
Olga Maciaszek-Sharma | f9cc51c16b | 2 years ago |
72 changed files with 585 additions and 2355 deletions
@ -1,49 +0,0 @@
@@ -1,49 +0,0 @@
|
||||
version: 2 |
||||
updates: |
||||
- package-ecosystem: "github-actions" |
||||
directory: "/" |
||||
target-branch: "3.1.x" # oldest OSS supported branch |
||||
schedule: |
||||
interval: "weekly" |
||||
- package-ecosystem: "github-actions" |
||||
directory: "/" |
||||
target-branch: "4.0.x" # oldest OSS supported branch |
||||
schedule: |
||||
interval: "weekly" |
||||
- package-ecosystem: "github-actions" |
||||
directory: "/" |
||||
target-branch: "main" |
||||
schedule: |
||||
interval: "weekly" |
||||
- package-ecosystem: maven |
||||
directory: / |
||||
schedule: |
||||
interval: daily |
||||
target-branch: 3.1.x |
||||
ignore: |
||||
# only upgrade patch versions for maintenance branch |
||||
- dependency-name: "*" |
||||
update-types: |
||||
- version-update:semver-major |
||||
- version-update:semver-minor |
||||
- package-ecosystem: maven |
||||
directory: / |
||||
schedule: |
||||
interval: daily |
||||
target-branch: 4.0.x |
||||
ignore: |
||||
# only upgrade patch versions for maintenance branch |
||||
- dependency-name: "*" |
||||
update-types: |
||||
- version-update:semver-major |
||||
- version-update:semver-minor |
||||
- package-ecosystem: maven |
||||
directory: / |
||||
schedule: |
||||
interval: daily |
||||
target-branch: main |
||||
ignore: |
||||
# only upgrade by minor or patch |
||||
- dependency-name: "*" |
||||
update-types: |
||||
- version-update:semver-major |
@ -1,32 +0,0 @@
@@ -1,32 +0,0 @@
|
||||
name: Deploy Docs |
||||
on: |
||||
push: |
||||
branches-ignore: [ gh-pages ] |
||||
tags: '**' |
||||
repository_dispatch: |
||||
types: request-build-reference # legacy |
||||
#schedule: |
||||
#- cron: '0 10 * * *' # Once per day at 10am UTC |
||||
workflow_dispatch: |
||||
permissions: |
||||
actions: write |
||||
jobs: |
||||
build: |
||||
runs-on: ubuntu-latest |
||||
# if: github.repository_owner == 'spring-cloud' |
||||
steps: |
||||
- name: Checkout |
||||
uses: actions/checkout@v4 |
||||
with: |
||||
ref: docs-build |
||||
fetch-depth: 1 |
||||
- name: Dispatch (partial build) |
||||
if: github.ref_type == 'branch' |
||||
env: |
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
||||
run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) -f build-refname=${{ github.ref_name }} |
||||
- name: Dispatch (full build) |
||||
if: github.ref_type == 'tag' |
||||
env: |
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
||||
run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) |
@ -1,2 +1 @@
@@ -1,2 +1 @@
|
||||
-DaltSnapshotDeploymentRepository=repo.spring.io::default::https://repo.spring.io/libs-snapshot-local |
||||
-P spring |
||||
-DaltSnapshotDeploymentRepository=repo.spring.io::default::https://repo.spring.io/libs-snapshot-local -P spring |
||||
|
Binary file not shown.
@ -1,18 +1 @@
@@ -1,18 +1 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one |
||||
# or more contributor license agreements. See the NOTICE file |
||||
# distributed with this work for additional information |
||||
# regarding copyright ownership. The ASF licenses this file |
||||
# to you under the Apache License, Version 2.0 (the |
||||
# "License"); you may not use this file except in compliance |
||||
# with the License. You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, |
||||
# software distributed under the License is distributed on an |
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||
# KIND, either express or implied. See the License for the |
||||
# specific language governing permissions and limitations |
||||
# under the License. |
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.4/apache-maven-3.9.4-bin.zip |
||||
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar |
||||
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip |
@ -1,39 +0,0 @@
@@ -1,39 +0,0 @@
|
||||
antora: |
||||
extensions: |
||||
- '@springio/antora-extensions/partial-build-extension' |
||||
- require: '@springio/antora-extensions/latest-version-extension' |
||||
- require: '@springio/antora-extensions/inject-collector-cache-config-extension' |
||||
- '@antora/collector-extension' |
||||
- '@antora/atlas-extension' |
||||
- require: '@springio/antora-extensions/root-component-extension' |
||||
root_component_name: 'cloud-openfeign' |
||||
- '@springio/antora-extensions/static-page-extension' |
||||
site: |
||||
title: Spring Cloud Openfeign |
||||
url: https://docs.spring.io/spring-cloud-openfeign/reference/ |
||||
content: |
||||
sources: |
||||
- url: ./.. |
||||
branches: HEAD |
||||
start_path: docs |
||||
worktrees: true |
||||
asciidoc: |
||||
attributes: |
||||
page-stackoverflow-url: https://stackoverflow.com/tags/spring-cloud |
||||
page-pagination: '' |
||||
hide-uri-scheme: '@' |
||||
tabs-sync-option: '@' |
||||
chomp: 'all' |
||||
extensions: |
||||
- '@asciidoctor/tabs' |
||||
- '@springio/asciidoctor-extensions' |
||||
sourcemap: true |
||||
urls: |
||||
latest_version_segment: '' |
||||
runtime: |
||||
log: |
||||
failure_level: warn |
||||
format: pretty |
||||
ui: |
||||
bundle: |
||||
url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.2/ui-bundle.zip |
@ -1,12 +0,0 @@
@@ -1,12 +0,0 @@
|
||||
name: cloud-openfeign |
||||
version: true |
||||
title: Spring Cloud OpenFeign |
||||
nav: |
||||
- modules/ROOT/nav.adoc |
||||
ext: |
||||
collector: |
||||
run: |
||||
command: ./mvnw --no-transfer-progress -B process-resources -Pdocs -pl docs -Dantora-maven-plugin.phase=none -Dgenerate-docs.phase=none -Dgenerate-readme.phase=none -Dgenerate-cloud-resources.phase=none -Dmaven-dependency-plugin-for-docs.phase=none -Dmaven-dependency-plugin-for-docs-classes.phase=none -DskipTests |
||||
local: true |
||||
scan: |
||||
dir: ./target/classes/antora-resources/ |
@ -1,4 +0,0 @@
@@ -1,4 +0,0 @@
|
||||
* xref:index.adoc[Introduction] |
||||
* xref:spring-cloud-openfeign.adoc[] |
||||
* xref:appendix.adoc[] |
||||
** xref:configprops.adoc[] |
@ -1,6 +0,0 @@
@@ -1,6 +0,0 @@
|
||||
[[configuration-properties]] |
||||
= Configuration Properties |
||||
|
||||
Below you can find a list of configuration properties. |
||||
|
||||
include::partial$_configprops.adoc[] |
@ -1 +0,0 @@
@@ -1 +0,0 @@
|
||||
include::intro.adoc[] |
@ -1,3 +0,0 @@
@@ -1,3 +0,0 @@
|
||||
:sc-ext: java |
||||
:project-full-name: Spring Cloud OpenFeign |
||||
:all: {asterisk}{asterisk} |
@ -1,113 +0,0 @@
@@ -1,113 +0,0 @@
|
||||
|=== |
||||
|Name | Default | Description |
||||
|
||||
|spring.cloud.compatibility-verifier.compatible-boot-versions | `+++3.2.x+++` | Default accepted versions for the Spring Boot dependency. You can set {@code x} for the patch version if you don't want to specify a concrete value. Example: {@code 3.4.x} |
||||
|spring.cloud.compatibility-verifier.enabled | `+++false+++` | Enables creation of Spring Cloud compatibility verification. |
||||
|spring.cloud.config.allow-override | `+++true+++` | Flag to indicate that {@link #isOverrideSystemProperties() systemPropertiesOverride} can be used. Set to false to prevent users from changing the default accidentally. Default true. |
||||
|spring.cloud.config.initialize-on-context-refresh | `+++false+++` | Flag to initialize bootstrap configuration on context refresh event. Default false. |
||||
|spring.cloud.config.override-none | `+++false+++` | Flag to indicate that when {@link #setAllowOverride(boolean) allowOverride} is true, external properties should take lowest priority and should not override any existing property sources (including local config files). Default false. This will only have an effect when using config first bootstrap. |
||||
|spring.cloud.config.override-system-properties | `+++true+++` | Flag to indicate that the external properties should override system properties. Default true. |
||||
|spring.cloud.decrypt-environment-post-processor.enabled | `+++true+++` | Enable the DecryptEnvironmentPostProcessor. |
||||
|spring.cloud.discovery.client.composite-indicator.enabled | `+++true+++` | Enables discovery client composite health indicator. |
||||
|spring.cloud.discovery.client.health-indicator.enabled | `+++true+++` | |
||||
|spring.cloud.discovery.client.health-indicator.include-description | `+++false+++` | |
||||
|spring.cloud.discovery.client.health-indicator.use-services-query | `+++true+++` | Whether or not the indicator should use {@link DiscoveryClient#getServices} to check its health. When set to {@code false} the indicator instead uses the lighter {@link DiscoveryClient#probe()}. This can be helpful in large deployments where the number of services returned makes the operation unnecessarily heavy. |
||||
|spring.cloud.discovery.client.simple.instances | | |
||||
|spring.cloud.discovery.client.simple.local.host | | |
||||
|spring.cloud.discovery.client.simple.local.instance-id | | |
||||
|spring.cloud.discovery.client.simple.local.metadata | | |
||||
|spring.cloud.discovery.client.simple.local.port | `+++0+++` | |
||||
|spring.cloud.discovery.client.simple.local.secure | `+++false+++` | |
||||
|spring.cloud.discovery.client.simple.local.service-id | | |
||||
|spring.cloud.discovery.client.simple.local.uri | | |
||||
|spring.cloud.discovery.client.simple.order | | |
||||
|spring.cloud.discovery.enabled | `+++true+++` | Enables discovery client health indicators. |
||||
|spring.cloud.features.enabled | `+++true+++` | Enables the features endpoint. |
||||
|spring.cloud.httpclientfactories.apache.enabled | `+++true+++` | Enables creation of Apache Http Client factory beans. |
||||
|spring.cloud.httpclientfactories.ok.enabled | `+++true+++` | Enables creation of OK Http Client factory beans. |
||||
|spring.cloud.hypermedia.refresh.fixed-delay | `+++5000+++` | |
||||
|spring.cloud.hypermedia.refresh.initial-delay | `+++10000+++` | |
||||
|spring.cloud.inetutils.default-hostname | `+++localhost+++` | The default hostname. Used in case of errors. |
||||
|spring.cloud.inetutils.default-ip-address | `+++127.0.0.1+++` | The default IP address. Used in case of errors. |
||||
|spring.cloud.inetutils.ignored-interfaces | | List of Java regular expressions for network interfaces that will be ignored. |
||||
|spring.cloud.inetutils.preferred-networks | | List of Java regular expressions for network addresses that will be preferred. |
||||
|spring.cloud.inetutils.timeout-seconds | `+++1+++` | Timeout, in seconds, for calculating hostname. |
||||
|spring.cloud.inetutils.use-only-site-local-interfaces | `+++false+++` | Whether to use only interfaces with site local addresses. See {@link InetAddress#isSiteLocalAddress()} for more details. |
||||
|spring.cloud.loadbalancer.call-get-with-request-on-delegates | `+++true+++` | If this flag is set to {@code true}, {@code ServiceInstanceListSupplier#get(Request request)} method will be implemented to call {@code delegate.get(request)} in classes assignable from {@code DelegatingServiceInstanceListSupplier} that don't already implement that method, with the exclusion of {@code CachingServiceInstanceListSupplier} and {@code HealthCheckServiceInstanceListSupplier}, which should be placed in the instance supplier hierarchy directly after the supplier performing instance retrieval over the network, before any request-based filtering is done, {@code true} by default. |
||||
|spring.cloud.loadbalancer.clients | | |
||||
|spring.cloud.loadbalancer.eager-load.clients | | |
||||
|spring.cloud.loadbalancer.health-check.initial-delay | `+++0+++` | Initial delay value for the HealthCheck scheduler. |
||||
|spring.cloud.loadbalancer.health-check.interval | `+++25s+++` | Interval for rerunning the HealthCheck scheduler. |
||||
|spring.cloud.loadbalancer.health-check.interval | `+++25s+++` | Interval for rerunning the HealthCheck scheduler. |
||||
|spring.cloud.loadbalancer.health-check.path | | Path at which the health-check request should be made. Can be set up per `serviceId`. A `default` value can be set up as well. If none is set up, `/actuator/health` will be used. |
||||
|spring.cloud.loadbalancer.health-check.port | | Path at which the health-check request should be made. If none is set, the port under which the requested service is available at the service instance. |
||||
|spring.cloud.loadbalancer.health-check.refetch-instances | `+++false+++` | Indicates whether the instances should be refetched by the `HealthCheckServiceInstanceListSupplier`. This can be used if the instances can be updated and the underlying delegate does not provide an ongoing flux. |
||||
|spring.cloud.loadbalancer.health-check.refetch-instances-interval | `+++25s+++` | Interval for refetching available service instances. |
||||
|spring.cloud.loadbalancer.health-check.repeat-health-check | `+++true+++` | Indicates whether health checks should keep repeating. It might be useful to set it to `false` if periodically refetching the instances, as every refetch will also trigger a healthcheck. |
||||
|spring.cloud.loadbalancer.health-check.update-results-list | `+++true+++` | Indicates whether the {@code healthCheckFlux} should emit on each alive {@link ServiceInstance} that has been retrieved. If set to {@code false}, the entire alive instances sequence is first collected into a list and only then emitted. |
||||
|spring.cloud.loadbalancer.hint | | Allows setting the value of <code>hint</code> that is passed on to the LoadBalancer request and can subsequently be used in {@link ReactiveLoadBalancer} implementations. |
||||
|spring.cloud.loadbalancer.hint-header-name | `+++X-SC-LB-Hint+++` | Allows setting the name of the header used for passing the hint for hint-based service instance filtering. |
||||
|spring.cloud.loadbalancer.retry.backoff.enabled | `+++false+++` | Indicates whether Reactor Retry backoffs should be applied. |
||||
|spring.cloud.loadbalancer.retry.backoff.jitter | `+++0.5+++` | Used to set `RetryBackoffSpec.jitter`. |
||||
|spring.cloud.loadbalancer.retry.backoff.max-backoff | `+++Long.MAX ms+++` | Used to set `RetryBackoffSpec.maxBackoff`. |
||||
|spring.cloud.loadbalancer.retry.backoff.min-backoff | `+++5 ms+++` | Used to set `RetryBackoffSpec#minBackoff`. |
||||
|spring.cloud.loadbalancer.retry.enabled | `+++true+++` | Enables LoadBalancer retries. |
||||
|spring.cloud.loadbalancer.retry.max-retries-on-next-service-instance | `+++1+++` | Number of retries to be executed on the next `ServiceInstance`. A `ServiceInstance` is chosen before each retry call. |
||||
|spring.cloud.loadbalancer.retry.max-retries-on-same-service-instance | `+++0+++` | Number of retries to be executed on the same `ServiceInstance`. |
||||
|spring.cloud.loadbalancer.retry.retry-on-all-exceptions | `+++false+++` | Indicates retries should be attempted for all exceptions, not only those specified in `retryableExceptions`. |
||||
|spring.cloud.loadbalancer.retry.retry-on-all-operations | `+++false+++` | Indicates retries should be attempted on operations other than `HttpMethod.GET`. |
||||
|spring.cloud.loadbalancer.retry.retryable-exceptions | `+++{}+++` | A `Set` of `Throwable` classes that should trigger a retry. |
||||
|spring.cloud.loadbalancer.retry.retryable-status-codes | `+++{}+++` | A `Set` of status codes that should trigger a retry. |
||||
|spring.cloud.loadbalancer.sticky-session.add-service-instance-cookie | `+++false+++` | Indicates whether a cookie with the newly selected instance should be added by LoadBalancer. |
||||
|spring.cloud.loadbalancer.sticky-session.instance-id-cookie-name | `+++sc-lb-instance-id+++` | The name of the cookie holding the preferred instance id. |
||||
|spring.cloud.loadbalancer.x-forwarded.enabled | `+++false+++` | To Enable X-Forwarded Headers. |
||||
|spring.cloud.openfeign.autoconfiguration.jackson.enabled | `+++true+++` | If true, PageJacksonModule and SortJacksonModule bean will be provided for Jackson page decoding. |
||||
|spring.cloud.openfeign.circuitbreaker.alphanumeric-ids.enabled | `+++false+++` | If true, Circuit Breaker ids will only contain alphanumeric characters to allow for configuration via configuration properties. |
||||
|spring.cloud.openfeign.circuitbreaker.enabled | `+++false+++` | If true, an OpenFeign client will be wrapped with a Spring Cloud CircuitBreaker circuit breaker. |
||||
|spring.cloud.openfeign.circuitbreaker.group.enabled | `+++false+++` | If true, an OpenFeign client will be wrapped with a Spring Cloud CircuitBreaker circuit breaker with with group. |
||||
|spring.cloud.openfeign.client.config | | |
||||
|spring.cloud.openfeign.client.decode-slash | `+++true+++` | Feign clients do not encode slash `/` characters by default. To change this behavior, set the `decodeSlash` to `false`. |
||||
|spring.cloud.openfeign.client.default-config | `+++default+++` | |
||||
|spring.cloud.openfeign.client.default-to-properties | `+++true+++` | |
||||
|spring.cloud.openfeign.client.refresh-enabled | `+++false+++` | Enables options value refresh capability for Feign. |
||||
|spring.cloud.openfeign.compression.request.enabled | `+++false+++` | Enables the request sent by Feign to be compressed. |
||||
|spring.cloud.openfeign.compression.request.mime-types | `+++[text/xml, application/xml, application/json]+++` | The list of supported mime types. |
||||
|spring.cloud.openfeign.compression.request.min-request-size | `+++2048+++` | The minimum threshold content size. |
||||
|spring.cloud.openfeign.compression.response.enabled | `+++false+++` | Enables the response from Feign to be compressed. |
||||
|spring.cloud.openfeign.encoder.charset-from-content-type | `+++false+++` | Indicates whether the charset should be derived from the {@code Content-Type} header. |
||||
|spring.cloud.openfeign.http2client.enabled | `+++false+++` | Enables the use of the Java11 HTTP 2 Client by Feign. |
||||
|spring.cloud.openfeign.httpclient.connection-timeout | `+++2000+++` | |
||||
|spring.cloud.openfeign.httpclient.connection-timer-repeat | `+++3000+++` | |
||||
|spring.cloud.openfeign.httpclient.disable-ssl-validation | `+++false+++` | |
||||
|spring.cloud.openfeign.httpclient.enabled | `+++true+++` | Enables the use of the Apache HTTP Client by Feign. |
||||
|spring.cloud.openfeign.httpclient.follow-redirects | `+++true+++` | |
||||
|spring.cloud.openfeign.httpclient.hc5.connection-request-timeout | `+++3+++` | Default value for connection request timeout. |
||||
|spring.cloud.openfeign.httpclient.hc5.connection-request-timeout-unit | | Default value for connection request timeout unit. |
||||
|spring.cloud.openfeign.httpclient.hc5.enabled | `+++false+++` | Enables the use of the Apache HTTP Client 5 by Feign. |
||||
|spring.cloud.openfeign.httpclient.hc5.pool-concurrency-policy | | Pool concurrency policies. |
||||
|spring.cloud.openfeign.httpclient.hc5.pool-reuse-policy | | Pool connection re-use policies. |
||||
|spring.cloud.openfeign.httpclient.hc5.socket-timeout | `+++5+++` | Default value for socket timeout. |
||||
|spring.cloud.openfeign.httpclient.hc5.socket-timeout-unit | | Default value for socket timeout unit. |
||||
|spring.cloud.openfeign.httpclient.http2.version | `+++HTTP_2+++` | Configure the protocols used by this client to communicate with remote servers. Uses {@link String} value of {@link HttpClient.Version}. |
||||
|spring.cloud.openfeign.httpclient.max-connections | `+++200+++` | |
||||
|spring.cloud.openfeign.httpclient.max-connections-per-route | `+++50+++` | |
||||
|spring.cloud.openfeign.httpclient.ok-http.protocols | | Configure the protocols used by this client to communicate with remote servers. Uses {@link String} values of {@link Protocol}. |
||||
|spring.cloud.openfeign.httpclient.ok-http.read-timeout | `+++60s+++` | {@link OkHttpClient} read timeout; defaults to 60 seconds. |
||||
|spring.cloud.openfeign.httpclient.time-to-live | `+++900+++` | |
||||
|spring.cloud.openfeign.httpclient.time-to-live-unit | | |
||||
|spring.cloud.openfeign.lazy-attributes-resolution | `+++false+++` | Switches @FeignClient attributes resolution mode to lazy. |
||||
|spring.cloud.openfeign.micrometer.enabled | `+++true+++` | Enables Micrometer capabilities for Feign. |
||||
|spring.cloud.openfeign.oauth2.clientRegistrationId | | Provides a clientId to be used with OAuth2. |
||||
|spring.cloud.openfeign.oauth2.enabled | `+++false+++` | Enables feign interceptor for managing oauth2 access token. |
||||
|spring.cloud.openfeign.okhttp.enabled | `+++false+++` | Enables the use of the OK HTTP Client by Feign. |
||||
|spring.cloud.refresh.additional-property-sources-to-retain | | Additional property sources to retain during a refresh. Typically only system property sources are retained. This property allows property sources, such as property sources created by EnvironmentPostProcessors to be retained as well. |
||||
|spring.cloud.refresh.enabled | `+++true+++` | Enables autoconfiguration for the refresh scope and associated features. |
||||
|spring.cloud.refresh.extra-refreshable | `+++true+++` | Additional class names for beans to post process into refresh scope. |
||||
|spring.cloud.refresh.never-refreshable | `+++true+++` | Comma separated list of class names for beans to never be refreshed or rebound. |
||||
|spring.cloud.refresh.on-restart.enabled | `+++true+++` | Enable refreshing context on start. |
||||
|spring.cloud.service-registry.auto-registration.enabled | `+++true+++` | Whether service auto-registration is enabled. Defaults to true. |
||||
|spring.cloud.service-registry.auto-registration.fail-fast | `+++false+++` | Whether startup fails if there is no AutoServiceRegistration. Defaults to false. |
||||
|spring.cloud.service-registry.auto-registration.register-management | `+++true+++` | Whether to register the management as a service. Defaults to true. |
||||
|spring.cloud.util.enabled | `+++true+++` | Enables creation of Spring Cloud utility beans. |
||||
|
||||
|=== |
@ -1,6 +0,0 @@
@@ -1,6 +0,0 @@
|
||||
[[observability-conventions]] |
||||
=== Observability - Conventions |
||||
|
||||
Below you can find a list of all `GlobalObservationConvention` and `ObservationConvention` declared by this project. |
||||
|
||||
|
@ -1,6 +0,0 @@
@@ -1,6 +0,0 @@
|
||||
[[observability-metrics]] |
||||
=== Observability - Metrics |
||||
|
||||
Below you can find a list of all metrics declared by this project. |
||||
|
||||
|
@ -1,6 +0,0 @@
@@ -1,6 +0,0 @@
|
||||
[[observability-spans]] |
||||
=== Observability - Spans |
||||
|
||||
Below you can find a list of all spans declared by this project. |
||||
|
||||
|
@ -1,20 +0,0 @@
@@ -1,20 +0,0 @@
|
||||
version: @antora-component.version@ |
||||
prerelease: @antora-component.prerelease@ |
||||
|
||||
asciidoc: |
||||
attributes: |
||||
attribute-missing: 'warn' |
||||
chomp: 'all' |
||||
project-root: @maven.multiModuleProjectDirectory@ |
||||
github-repo: @docs.main@ |
||||
github-raw: https://raw.githubusercontent.com/spring-cloud/@docs.main@/@github-tag@ |
||||
github-code: https://github.com/spring-cloud/@docs.main@/tree/@github-tag@ |
||||
github-issues: https://github.com/spring-cloud/@docs.main@/issues/ |
||||
github-wiki: https://github.com/spring-cloud/@docs.main@/wiki |
||||
spring-cloud-version: @project.version@ |
||||
github-tag: @github-tag@ |
||||
version-type: @version-type@ |
||||
docs-url: https://docs.spring.io/@docs.main@/docs/@project.version@ |
||||
raw-docs-url: https://raw.githubusercontent.com/spring-cloud/@docs.main@/@github-tag@ |
||||
project-version: @project.version@ |
||||
project-name: @docs.main@ |
@ -1,24 +1,25 @@
@@ -1,24 +1,25 @@
|
||||
image::https://github.com/spring-cloud/spring-cloud-openfeign/workflows/Build/badge.svg?branch=main&style=svg["Build",link="https://github.com/spring-cloud/spring-cloud-openfeign/actions"] |
||||
|
||||
image:https://codecov.io/gh/spring-cloud/spring-cloud-openfeign/branch/main/graph/badge.svg["Codecov", link="https://app.codecov.io/gh/spring-cloud/spring-cloud-openfeign/tree/main"] |
||||
image:https://codecov.io/gh/spring-cloud/spring-cloud-openfeign/branch/main/graph/badge.svg["Codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-openfeign"] |
||||
|
||||
image:https://api.codacy.com/project/badge/Grade/97b04c4e609c4b4f86b415e4437a6484["Codacy code quality", link="https://www.codacy.com/app/Spring-Cloud/spring-cloud-openfeign?utm_source=github.com&utm_medium=referral&utm_content=spring-cloud/spring-cloud-openfeign&utm_campaign=Badge_Grade"] |
||||
|
||||
include::_attributes.adoc[] |
||||
|
||||
include::intro.adoc[] |
||||
|
||||
[[features]] |
||||
== Features |
||||
|
||||
* Declarative REST Client: Feign creates a dynamic implementation of an interface decorated with JAX-RS or Spring MVC annotations |
||||
|
||||
[[building]] |
||||
== Building |
||||
|
||||
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/main/docs/modules/ROOT/partials/building.adoc[] |
||||
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/main/docs/src/main/asciidoc/building-jdk8.adoc[] |
||||
|
||||
[[contributing]] |
||||
== Contributing |
||||
|
||||
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/main/docs/modules/ROOT/partials/contributing-docs.adoc[] |
||||
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/main/docs/src/main/asciidoc/contributing.adoc[] |
||||
|
||||
[[license]] |
||||
== License |
||||
|
||||
The project license file is available https://raw.githubusercontent.com/spring-cloud/spring-cloud-openfeign/main/LICENSE.txt[here]. |
||||
|
@ -1,6 +1,8 @@
@@ -1,6 +1,8 @@
|
||||
:doctype: book |
||||
:idprefix: |
||||
:idseparator: - |
||||
:toc: left |
||||
:toclevels: 4 |
||||
:tabsize: 4 |
||||
:numbered: |
||||
:sectanchors: |
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
|=== |
||||
|Name | Default | Description |
||||
|
||||
|spring.cloud.openfeign.autoconfiguration.jackson.enabled | `false` | If true, PageJacksonModule and SortJacksonModule bean will be provided for Jackson page decoding. |
||||
|spring.cloud.openfeign.circuitbreaker.enabled | `false` | If true, an OpenFeign client will be wrapped with a Spring Cloud CircuitBreaker circuit breaker. |
||||
|spring.cloud.openfeign.circuitbreaker.group.enabled | `false` | If true, an OpenFeign client will be wrapped with a Spring Cloud CircuitBreaker circuit breaker with with group. |
||||
|spring.cloud.openfeign.client.config | | |
||||
|spring.cloud.openfeign.client.decode-slash | `true` | Feign clients do not encode slash `/` characters by default. To change this behavior, set the `decodeSlash` to `false`. |
||||
|spring.cloud.openfeign.client.default-config | `default` | |
||||
|spring.cloud.openfeign.client.default-to-properties | `true` | |
||||
|spring.cloud.openfeign.client.refresh-enabled | `false` | Enables options value refresh capability for Feign. |
||||
|spring.cloud.openfeign.compression.request.enabled | `false` | Enables the request sent by Feign to be compressed. |
||||
|spring.cloud.openfeign.compression.request.mime-types | `[text/xml, application/xml, application/json]` | The list of supported mime types. |
||||
|spring.cloud.openfeign.compression.request.min-request-size | `2048` | The minimum threshold content size. |
||||
|spring.cloud.openfeign.compression.response.enabled | `false` | Enables the response from Feign to be compressed. |
||||
|spring.cloud.openfeign.encoder.charset-from-content-type | `false` | Indicates whether the charset should be derived from the {@code Content-Type} header. |
||||
|spring.cloud.openfeign.httpclient.connection-timeout | `2000` | |
||||
|spring.cloud.openfeign.httpclient.connection-timer-repeat | `3000` | |
||||
|spring.cloud.openfeign.httpclient.disable-ssl-validation | `false` | |
||||
|spring.cloud.openfeign.httpclient.enabled | `true` | Enables the use of the Apache HTTP Client by Feign. |
||||
|spring.cloud.openfeign.httpclient.follow-redirects | `true` | |
||||
|spring.cloud.openfeign.httpclient.hc5.enabled | `false` | Enables the use of the Apache HTTP Client 5 by Feign. |
||||
|spring.cloud.openfeign.httpclient.hc5.pool-concurrency-policy | | Pool concurrency policies. |
||||
|spring.cloud.openfeign.httpclient.hc5.pool-reuse-policy | | Pool connection re-use policies. |
||||
|spring.cloud.openfeign.httpclient.hc5.socket-timeout | `5` | Default value for socket timeout. |
||||
|spring.cloud.openfeign.httpclient.hc5.socket-timeout-unit | | Default value for socket timeout unit. |
||||
|spring.cloud.openfeign.httpclient.max-connections | `200` | |
||||
|spring.cloud.openfeign.httpclient.max-connections-per-route | `50` | |
||||
|spring.cloud.openfeign.httpclient.ok-http.read-timeout | `60s` | {@link OkHttpClient} read timeout; defaults to 60 seconds. |
||||
|spring.cloud.openfeign.httpclient.time-to-live | `900` | |
||||
|spring.cloud.openfeign.httpclient.time-to-live-unit | | |
||||
|spring.cloud.openfeign.micrometer.enabled | `true` | Enables Micrometer capabilities for Feign. |
||||
|spring.cloud.openfeign.oauth2.enabled | `false` | Enables feign interceptor for managing oauth2 access token. |
||||
|spring.cloud.openfeign.oauth2.load-balanced | `false` | Enables load balancing for oauth2 access token provider. |
||||
|spring.cloud.openfeign.okhttp.enabled | `false` | Enables the use of the OK HTTP Client by Feign. |
||||
|
||||
|=== |
@ -1,13 +1,14 @@
@@ -1,13 +1,14 @@
|
||||
:numbered!: |
||||
[appendix] |
||||
[[common-application-properties]] |
||||
= Common application properties |
||||
:page-section-summary-toc: 1 |
||||
== Common application properties |
||||
|
||||
include::_attributes.adoc[] |
||||
|
||||
Various properties can be specified inside your `application.properties` file, inside your `application.yml` file, or as command line switches. |
||||
This appendix provides a list of common Spring Cloud OpenFeign properties and references to the underlying classes that consume them. |
||||
This appendix provides a list of common {project-full-name} properties and references to the underlying classes that consume them. |
||||
|
||||
NOTE: Property contributions can come from additional jar files on your classpath, so you should not consider this an exhaustive list. |
||||
Also, you can define your own properties. |
||||
|
||||
include::_configprops.adoc[] |
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
include::spring-cloud-openfeign.adoc[] |
@ -1,6 +1,3 @@
@@ -1,6 +1,3 @@
|
||||
[[introduction]] |
||||
= Spring Cloud OpenFeign |
||||
|
||||
This project provides OpenFeign integrations for Spring Boot apps through autoconfiguration |
||||
and binding to the Spring Environment and other Spring programming model idioms. |
||||
|
@ -1,49 +0,0 @@
@@ -1,49 +0,0 @@
|
||||
/* |
||||
* Copyright 2013-2023 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.cloud.openfeign; |
||||
|
||||
import feign.Target; |
||||
|
||||
/** |
||||
* A {@link HardCodedTarget} implementation that resolves url from properties when the |
||||
* initial call is made. Using it allows specifying the url at runtime in an AOT-packaged |
||||
* application or a native image by setting the value of the |
||||
* `spring.cloud.openfeign.client.config.[clientId].url`. |
||||
* |
||||
* @author Olga Maciaszek-Sharma |
||||
* @see FeignClientProperties.FeignClientConfiguration#getUrl() |
||||
*/ |
||||
public class PropertyBasedTarget<T> extends Target.HardCodedTarget<T> { |
||||
|
||||
private String url; |
||||
|
||||
private final FeignClientProperties.FeignClientConfiguration config; |
||||
|
||||
public PropertyBasedTarget(Class<T> type, String name, FeignClientProperties.FeignClientConfiguration config) { |
||||
super(type, name, config.getUrl()); |
||||
this.config = config; |
||||
} |
||||
|
||||
@Override |
||||
public String url() { |
||||
if (url == null) { |
||||
url = config.getUrl(); |
||||
} |
||||
return url; |
||||
} |
||||
|
||||
} |
@ -1,45 +0,0 @@
@@ -1,45 +0,0 @@
|
||||
/* |
||||
* Copyright 2013-2023 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.cloud.openfeign.clientconfig; |
||||
|
||||
import java.net.http.HttpClient; |
||||
import java.time.Duration; |
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
||||
import org.springframework.cloud.openfeign.support.FeignHttpClientProperties; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
|
||||
/** |
||||
* Default configuration for {@link HttpClient}. |
||||
* |
||||
* @author changjin wei(魏昌进) |
||||
*/ |
||||
@Configuration(proxyBeanMethods = false) |
||||
@ConditionalOnMissingBean(HttpClient.class) |
||||
public class Http2ClientFeignConfiguration { |
||||
|
||||
@Bean |
||||
public HttpClient httpClient(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())).build(); |
||||
} |
||||
|
||||
} |
@ -1,51 +0,0 @@
@@ -1,51 +0,0 @@
|
||||
/* |
||||
* Copyright 2013-2023 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.cloud.openfeign.encoding; |
||||
|
||||
import feign.Client; |
||||
import feign.okhttp.OkHttpClient; |
||||
|
||||
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
||||
import org.springframework.context.annotation.Condition; |
||||
|
||||
/** |
||||
* A {@link Condition} that verifies whether the conditions for creating Feign |
||||
* {@link Client} beans that either are of type {@link OkHttpClient} or have a delegate of |
||||
* type {@link OkHttpClient} are not met. |
||||
* |
||||
* @author Olga Maciaszek-Sharma |
||||
* @since 4.0.2 |
||||
*/ |
||||
public class OkHttpFeignClientBeanMissingCondition extends AnyNestedCondition { |
||||
|
||||
public OkHttpFeignClientBeanMissingCondition() { |
||||
super(ConfigurationPhase.REGISTER_BEAN); |
||||
} |
||||
|
||||
@ConditionalOnMissingClass("feign.okhttp.OkHttpClient") |
||||
static class FeignOkHttpClientPresent { |
||||
|
||||
} |
||||
|
||||
@ConditionalOnProperty(value = "spring.cloud.openfeign.okhttp.enabled", havingValue = "false") |
||||
static class FeignOkHttpClientEnabled { |
||||
|
||||
} |
||||
|
||||
} |
@ -1,76 +0,0 @@
@@ -1,76 +0,0 @@
|
||||
/* |
||||
* Copyright 2013-2023 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.cloud.openfeign.loadbalancer; |
||||
|
||||
import java.net.http.HttpClient; |
||||
import java.util.List; |
||||
|
||||
import feign.Client; |
||||
import feign.http2client.Http2Client; |
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties; |
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; |
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; |
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClientsProperties; |
||||
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Conditional; |
||||
import org.springframework.context.annotation.Configuration; |
||||
|
||||
/** |
||||
* Configuration instantiating a {@link LoadBalancerClient}-based {@link Client} object |
||||
* that uses {@link Http2Client} under the hood. |
||||
* |
||||
* @author changjin wei(魏昌进) |
||||
*/ |
||||
@Configuration(proxyBeanMethods = false) |
||||
@ConditionalOnClass({ Http2Client.class, HttpClient.class }) |
||||
@ConditionalOnBean({ LoadBalancerClient.class, LoadBalancerClientFactory.class }) |
||||
@ConditionalOnProperty("spring.cloud.openfeign.http2client.enabled") |
||||
@EnableConfigurationProperties(LoadBalancerClientsProperties.class) |
||||
class Http2ClientFeignLoadBalancerConfiguration { |
||||
|
||||
@Bean |
||||
@ConditionalOnMissingBean |
||||
@Conditional(OnRetryNotEnabledCondition.class) |
||||
public Client feignClient(LoadBalancerClient loadBalancerClient, HttpClient httpClient, |
||||
LoadBalancerClientFactory loadBalancerClientFactory, |
||||
List<LoadBalancerFeignRequestTransformer> transformers) { |
||||
Client delegate = new Http2Client(httpClient); |
||||
return new FeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancerClientFactory, |
||||
transformers); |
||||
} |
||||
|
||||
@Bean |
||||
@ConditionalOnMissingBean |
||||
@ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate") |
||||
@ConditionalOnBean(LoadBalancedRetryFactory.class) |
||||
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.retry.enabled", havingValue = "true", |
||||
matchIfMissing = true) |
||||
public Client feignRetryClient(LoadBalancerClient loadBalancerClient, HttpClient httpClient, |
||||
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerClientFactory loadBalancerClientFactory, |
||||
List<LoadBalancerFeignRequestTransformer> transformers) { |
||||
Client delegate = new Http2Client(httpClient); |
||||
return new RetryableFeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancedRetryFactory, |
||||
loadBalancerClientFactory, transformers); |
||||
} |
||||
|
||||
} |
@ -1,70 +0,0 @@
@@ -1,70 +0,0 @@
|
||||
/* |
||||
* Copyright 2013-2023 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.cloud.openfeign; |
||||
|
||||
import java.net.http.HttpClient; |
||||
import java.time.Duration; |
||||
import java.util.Optional; |
||||
|
||||
import org.junit.jupiter.api.AfterEach; |
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.boot.WebApplicationType; |
||||
import org.springframework.boot.builder.SpringApplicationBuilder; |
||||
import org.springframework.context.ConfigurableApplicationContext; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* @author changjin wei(魏昌进) |
||||
*/ |
||||
class FeignHttp2ClientConfigurationTests { |
||||
|
||||
private ConfigurableApplicationContext context; |
||||
|
||||
@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(); |
||||
} |
||||
|
||||
@AfterEach |
||||
void tearDown() { |
||||
if (context != null) { |
||||
context.close(); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
void shouldConfigureConnectTimeout() { |
||||
HttpClient httpClient = context.getBean(HttpClient.class); |
||||
|
||||
assertThat(httpClient.connectTimeout()).isEqualTo(Optional.ofNullable(Duration.ofMillis(15))); |
||||
} |
||||
|
||||
@Test |
||||
void shouldResolveVersionFromProperties() { |
||||
HttpClient httpClient = context.getBean(HttpClient.class); |
||||
|
||||
assertThat(httpClient.version()).isEqualTo(HttpClient.Version.HTTP_1_1); |
||||
} |
||||
|
||||
} |
@ -1,197 +0,0 @@
@@ -1,197 +0,0 @@
|
||||
/* |
||||
* Copyright 2022-2023 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.cloud.openfeign.aot; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.function.Consumer; |
||||
|
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.aot.generate.GeneratedClass; |
||||
import org.springframework.aot.generate.GeneratedMethods; |
||||
import org.springframework.aot.generate.GenerationContext; |
||||
import org.springframework.aot.generate.MethodReference; |
||||
import org.springframework.aot.hint.RuntimeHints; |
||||
import org.springframework.aot.test.generate.TestGenerationContext; |
||||
import org.springframework.beans.MutablePropertyValues; |
||||
import org.springframework.beans.PropertyValue; |
||||
import org.springframework.beans.PropertyValues; |
||||
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotContribution; |
||||
import org.springframework.beans.factory.aot.BeanFactoryInitializationCode; |
||||
import org.springframework.beans.factory.config.BeanDefinition; |
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues; |
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory; |
||||
import org.springframework.beans.factory.support.GenericBeanDefinition; |
||||
import org.springframework.beans.factory.support.RootBeanDefinition; |
||||
import org.springframework.cloud.openfeign.FeignClient; |
||||
import org.springframework.cloud.openfeign.FeignClientFactory; |
||||
import org.springframework.cloud.openfeign.FeignClientSpecification; |
||||
import org.springframework.context.support.GenericApplicationContext; |
||||
import org.springframework.javapoet.TypeSpec; |
||||
import org.springframework.web.bind.annotation.PostMapping; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.mockito.Mockito.mock; |
||||
import static org.mockito.Mockito.when; |
||||
import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.proxies; |
||||
import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.reflection; |
||||
|
||||
/** |
||||
* Tests for {@link FeignClientBeanFactoryInitializationAotProcessor}. |
||||
* |
||||
* @author Olga Maciaszek-Sharma |
||||
*/ |
||||
class FeignClientBeanFactoryInitializationAotProcessorTests { |
||||
|
||||
private static final String BEAN_DEFINITION_CLASS_NAME = "org.springframework.cloud.openfeign.aot.FeignClientBeanFactoryInitializationAotProcessorTests$TestClient"; |
||||
|
||||
private final TestGenerationContext generationContext = new TestGenerationContext(); |
||||
|
||||
private final FeignClientFactory feignClientFactory = mock(FeignClientFactory.class); |
||||
|
||||
private final BeanFactoryInitializationCode beanFactoryInitializationCode = new MockBeanFactoryInitializationCode( |
||||
generationContext); |
||||
|
||||
@BeforeEach |
||||
void setUp() { |
||||
Map<String, FeignClientSpecification> configurations = Map.of("test", |
||||
new FeignClientSpecification("test", TestClient.class.getCanonicalName(), new Class<?>[] {})); |
||||
when(feignClientFactory.getConfigurations()).thenReturn(configurations); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
void shouldGenerateBeanInitializationCodeAndRegisterHints() { |
||||
DefaultListableBeanFactory beanFactory = beanFactory(); |
||||
GenericApplicationContext context = new GenericApplicationContext(beanFactory); |
||||
FeignClientBeanFactoryInitializationAotProcessor processor = new FeignClientBeanFactoryInitializationAotProcessor( |
||||
context, feignClientFactory); |
||||
|
||||
BeanFactoryInitializationAotContribution contribution = processor.processAheadOfTime(beanFactory); |
||||
assertThat(contribution).isNotNull(); |
||||
|
||||
verifyContribution((FeignClientBeanFactoryInitializationAotProcessor.AotContribution) contribution); |
||||
contribution.applyTo(generationContext, beanFactoryInitializationCode); |
||||
|
||||
RuntimeHints hints = generationContext.getRuntimeHints(); |
||||
assertThat(reflection().onType(TestReturnType.class)).accepts(hints); |
||||
assertThat(reflection().onType(TestArgType.class)).accepts(hints); |
||||
assertThat(proxies().forInterfaces(TestClient.class)).accepts(hints); |
||||
} |
||||
|
||||
private static void verifyContribution( |
||||
FeignClientBeanFactoryInitializationAotProcessor.AotContribution contribution) { |
||||
BeanDefinition contributionBeanDefinition = contribution.getFeignClientBeanDefinitions() |
||||
.get(TestClient.class.getCanonicalName()); |
||||
assertThat(contributionBeanDefinition.getBeanClassName()).isEqualTo(BEAN_DEFINITION_CLASS_NAME); |
||||
PropertyValues propertyValues = contributionBeanDefinition.getPropertyValues(); |
||||
assertThat(propertyValues).isNotEmpty(); |
||||
assertThat(((String[]) propertyValues.getPropertyValue("qualifiers").getValue())).containsExactly("test"); |
||||
assertThat(propertyValues.getPropertyValue("type").getValue()).isEqualTo(TestClient.class.getCanonicalName()); |
||||
assertThat(propertyValues.getPropertyValue("fallback").getValue()).isEqualTo(String.class); |
||||
} |
||||
|
||||
private DefaultListableBeanFactory beanFactory() { |
||||
GenericBeanDefinition beanDefinition = new GenericBeanDefinition(new RootBeanDefinition(TestClient.class, |
||||
new ConstructorArgumentValues(), |
||||
new MutablePropertyValues(List.of(new PropertyValue("type", TestClient.class.getCanonicalName()), |
||||
new PropertyValue("qualifiers", new String[] { "test" }), |
||||
new PropertyValue("fallback", String.class), |
||||
new PropertyValue("fallbackFactory", Void.class))))); |
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); |
||||
beanFactory.registerBeanDefinition(TestClient.class.getCanonicalName(), beanDefinition); |
||||
return beanFactory; |
||||
} |
||||
|
||||
@FeignClient |
||||
interface TestClient { |
||||
|
||||
@PostMapping("/test") |
||||
TestReturnType test(TestArgType arg); |
||||
|
||||
} |
||||
|
||||
@SuppressWarnings("NullableProblems") |
||||
static class MockBeanFactoryInitializationCode implements BeanFactoryInitializationCode { |
||||
|
||||
private static final Consumer<TypeSpec.Builder> emptyTypeCustomizer = type -> { |
||||
}; |
||||
|
||||
private final GeneratedClass generatedClass; |
||||
|
||||
MockBeanFactoryInitializationCode(GenerationContext generationContext) { |
||||
generatedClass = generationContext.getGeneratedClasses().addForFeature("Test", emptyTypeCustomizer); |
||||
} |
||||
|
||||
@Override |
||||
public GeneratedMethods getMethods() { |
||||
return generatedClass.getMethods(); |
||||
} |
||||
|
||||
@Override |
||||
public void addInitializer(MethodReference methodReference) { |
||||
new ArrayList<>(); |
||||
} |
||||
|
||||
} |
||||
|
||||
static class TestReturnType { |
||||
|
||||
private String test; |
||||
|
||||
TestReturnType(String test) { |
||||
this.test = test; |
||||
} |
||||
|
||||
TestReturnType() { |
||||
} |
||||
|
||||
String getTest() { |
||||
return test; |
||||
} |
||||
|
||||
void setTest(String test) { |
||||
this.test = test; |
||||
} |
||||
|
||||
} |
||||
|
||||
static class TestArgType { |
||||
|
||||
private String test; |
||||
|
||||
TestArgType(String test) { |
||||
this.test = test; |
||||
} |
||||
|
||||
TestArgType() { |
||||
} |
||||
|
||||
String getTest() { |
||||
return test; |
||||
} |
||||
|
||||
void setTest(String test) { |
||||
this.test = test; |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -1,134 +0,0 @@
@@ -1,134 +0,0 @@
|
||||
/* |
||||
* Copyright 2013-2023 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.cloud.openfeign.circuitbreaker; |
||||
|
||||
import java.util.function.Function; |
||||
import java.util.function.Supplier; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.beans.factory.FactoryBean; |
||||
import org.springframework.boot.autoconfigure.AutoConfigurations; |
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; |
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner; |
||||
import org.springframework.cloud.client.circuitbreaker.CircuitBreaker; |
||||
import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; |
||||
import org.springframework.cloud.client.circuitbreaker.ConfigBuilder; |
||||
import org.springframework.cloud.openfeign.EnableFeignClients; |
||||
import org.springframework.cloud.openfeign.FeignAutoConfiguration; |
||||
import org.springframework.cloud.openfeign.FeignClient; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* @author 黄学敏(huangxuemin) |
||||
*/ |
||||
class FallbackSupportFactoryBeanTests { |
||||
|
||||
private static final String FACTORY_BEAN_FALLBACK_MESSAGE = "factoryBean fallback message"; |
||||
|
||||
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); |
||||
} |
||||
} |
||||
}; |
||||
} |
||||
|
||||
@Override |
||||
protected ConfigBuilder configBuilder(String id) { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public void configureDefault(Function defaultConfiguration) { |
||||
|
||||
} |
||||
}).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(); |
||||
}); |
||||
} |
||||
|
||||
@Configuration(proxyBeanMethods = false) |
||||
@EnableFeignClients(clients = { FallbackSupportFactoryBeanTests.OriginalFeign.class, |
||||
FallbackSupportFactoryBeanTests.FactoryBeanFallbackFeign.class }) |
||||
@EnableAutoConfiguration |
||||
private static class TestConfiguration { |
||||
|
||||
} |
||||
|
||||
@FeignClient(name = "original", url = "https://original", fallback = OriginalFeignFallback.class) |
||||
interface OriginalFeign { |
||||
|
||||
@GetMapping("/") |
||||
String get(); |
||||
|
||||
} |
||||
|
||||
@FeignClient(name = "factoryBean", url = "https://factoryBean", fallback = FactoryBeanFallbackFeignFallback.class) |
||||
interface FactoryBeanFallbackFeign { |
||||
|
||||
@GetMapping("/") |
||||
String get(); |
||||
|
||||
} |
||||
|
||||
private static class FactoryBeanFallbackFeignFallback implements FactoryBean<FactoryBeanFallbackFeign> { |
||||
|
||||
@Override |
||||
public FactoryBeanFallbackFeign getObject() { |
||||
return () -> FACTORY_BEAN_FALLBACK_MESSAGE; |
||||
} |
||||
|
||||
@Override |
||||
public Class<?> getObjectType() { |
||||
return FactoryBeanFallbackFeign.class; |
||||
} |
||||
|
||||
} |
||||
|
||||
private static class OriginalFeignFallback implements OriginalFeign { |
||||
|
||||
@Override |
||||
public String get() { |
||||
return ORIGINAL_FALLBACK_MESSAGE; |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -1,79 +0,0 @@
@@ -1,79 +0,0 @@
|
||||
/* |
||||
* Copyright 2013-2023 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.cloud.openfeign.protocol; |
||||
|
||||
import java.lang.reflect.Field; |
||||
|
||||
import feign.Client; |
||||
import okhttp3.Protocol; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; |
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; |
||||
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients; |
||||
import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient; |
||||
import org.springframework.cloud.openfeign.test.NoSecurityConfiguration; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.context.annotation.Import; |
||||
import org.springframework.test.annotation.DirtiesContext; |
||||
import org.springframework.util.ReflectionUtils; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* @author changjin wei(魏昌进) |
||||
*/ |
||||
@SpringBootTest(classes = FeignOkHttpProtocolsTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, |
||||
value = { "spring.application.name=feignclienttest", "spring.cloud.openfeign.circuitbreaker.enabled=false", |
||||
"spring.cloud.openfeign.httpclient.hc5.enabled=false", "spring.cloud.openfeign.okhttp.enabled=true", |
||||
"spring.cloud.httpclientfactories.ok.enabled=true", "spring.cloud.loadbalancer.retry.enabled=false", |
||||
"server.http2.enabled=true", "spring.cloud.openfeign.httpclient.okhttp.protocols=H2_PRIOR_KNOWLEDGE" }) |
||||
@DirtiesContext |
||||
class FeignOkHttpProtocolsTests { |
||||
|
||||
@Autowired |
||||
private Client feignClient; |
||||
|
||||
@Test |
||||
void shouldCreateCorrectFeignClientBeanWithProtocolFromProperties() { |
||||
assertThat(feignClient).isInstanceOf(FeignBlockingLoadBalancerClient.class); |
||||
FeignBlockingLoadBalancerClient client = (FeignBlockingLoadBalancerClient) feignClient; |
||||
Client delegate = client.getDelegate(); |
||||
assertThat(delegate).isInstanceOf(feign.okhttp.OkHttpClient.class); |
||||
okhttp3.OkHttpClient OkHttpClient = (okhttp3.OkHttpClient) getField(delegate, "delegate"); |
||||
assertThat(OkHttpClient.protocols()).containsExactly(Protocol.H2_PRIOR_KNOWLEDGE); |
||||
} |
||||
|
||||
protected Object getField(Object target, String name) { |
||||
Field field = ReflectionUtils.findField(target.getClass(), name); |
||||
ReflectionUtils.makeAccessible(field); |
||||
return ReflectionUtils.getField(field, target); |
||||
} |
||||
|
||||
@Configuration(proxyBeanMethods = false) |
||||
@EnableAutoConfiguration |
||||
@RestController |
||||
@LoadBalancerClients |
||||
@Import(NoSecurityConfiguration.class) |
||||
protected static class Application { |
||||
|
||||
} |
||||
|
||||
} |
@ -1,81 +0,0 @@
@@ -1,81 +0,0 @@
|
||||
/* |
||||
* Copyright 2013-2023 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.cloud.openfeign.test; |
||||
|
||||
import java.net.http.HttpClient; |
||||
|
||||
import feign.Client; |
||||
import feign.http2client.Http2Client; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.boot.SpringBootConfiguration; |
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; |
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
import org.springframework.cloud.openfeign.FeignClient; |
||||
import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.test.annotation.DirtiesContext; |
||||
import org.springframework.test.util.ReflectionTestUtils; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* @author changjin wei(魏昌进) |
||||
*/ |
||||
@SpringBootTest(properties = { "spring.cloud.openfeign.http2client.enabled= true", |
||||
"spring.cloud.openfeign.httpclient.hc5.enabled= false", "spring.cloud.loadbalancer.retry.enabled= false" }) |
||||
@DirtiesContext |
||||
class Http2ClientConfigurationTests { |
||||
|
||||
@Autowired |
||||
FeignBlockingLoadBalancerClient feignClient; |
||||
|
||||
private static final HttpClient defaultHttpClient = HttpClient.newHttpClient(); |
||||
|
||||
@Test |
||||
void shouldInstantiateFeignHttp2Client() { |
||||
Client delegate = feignClient.getDelegate(); |
||||
assertThat(delegate instanceof Http2Client).isTrue(); |
||||
Http2Client http2Client = (Http2Client) delegate; |
||||
HttpClient httpClient = getField(http2Client, "client"); |
||||
assertThat(httpClient).isEqualTo(defaultHttpClient); |
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
protected <T> T getField(Object target, String name) { |
||||
Object value = ReflectionTestUtils.getField(target, target.getClass(), name); |
||||
return (T) value; |
||||
} |
||||
|
||||
@FeignClient(name = "foo") |
||||
interface FooClient { |
||||
|
||||
} |
||||
|
||||
@SpringBootConfiguration |
||||
@EnableAutoConfiguration |
||||
static class TestConfig { |
||||
|
||||
@Bean |
||||
public HttpClient client() { |
||||
return defaultHttpClient; |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -1,256 +0,0 @@
@@ -1,256 +0,0 @@
|
||||
/* |
||||
* Copyright 2013-2023 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.cloud.openfeign.valid; |
||||
|
||||
import java.util.Objects; |
||||
|
||||
import feign.Client; |
||||
import feign.http2client.Http2Client; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; |
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; |
||||
import org.springframework.boot.test.web.server.LocalServerPort; |
||||
import org.springframework.cloud.client.DefaultServiceInstance; |
||||
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; |
||||
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients; |
||||
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; |
||||
import org.springframework.cloud.loadbalancer.support.ServiceInstanceListSuppliers; |
||||
import org.springframework.cloud.openfeign.EnableFeignClients; |
||||
import org.springframework.cloud.openfeign.FeignClient; |
||||
import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient; |
||||
import org.springframework.cloud.openfeign.test.NoSecurityConfiguration; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.context.annotation.Import; |
||||
import org.springframework.http.ResponseEntity; |
||||
import org.springframework.test.annotation.DirtiesContext; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.PatchMapping; |
||||
import org.springframework.web.bind.annotation.PathVariable; |
||||
import org.springframework.web.bind.annotation.RequestBody; |
||||
import org.springframework.web.bind.annotation.RequestHeader; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* @author changjin wei(魏昌进) |
||||
*/ |
||||
@SpringBootTest(classes = FeignHttp2ClientTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, |
||||
value = { "spring.application.name=feignclienttest", "spring.cloud.openfeign.circuitbreaker.enabled=false", |
||||
"spring.cloud.openfeign.httpclient.hc5.enabled=false", |
||||
"spring.cloud.openfeign.http2client.enabled=true", "spring.cloud.loadbalancer.retry.enabled=false" }) |
||||
@DirtiesContext |
||||
class FeignHttp2ClientTests { |
||||
|
||||
@Autowired |
||||
private TestClient testClient; |
||||
|
||||
@Autowired |
||||
private Client feignClient; |
||||
|
||||
@Autowired |
||||
private UserClient userClient; |
||||
|
||||
@Test |
||||
void testSimpleType() { |
||||
Hello hello = testClient.getHello(); |
||||
assertThat(hello).as("hello was null").isNotNull(); |
||||
assertThat(hello).as("first hello didn't match").isEqualTo(new Hello("hello world 1")); |
||||
} |
||||
|
||||
@Test |
||||
void testPatch() { |
||||
ResponseEntity<Void> response = testClient.patchHello(new Hello("foo")); |
||||
assertThat(response).isNotNull(); |
||||
String header = response.getHeaders().getFirst("x-hello"); |
||||
assertThat(header).isEqualTo("hello world patch"); |
||||
} |
||||
|
||||
@Test |
||||
void testFeignClientType() { |
||||
assertThat(feignClient).isInstanceOf(FeignBlockingLoadBalancerClient.class); |
||||
FeignBlockingLoadBalancerClient client = (FeignBlockingLoadBalancerClient) feignClient; |
||||
Client delegate = client.getDelegate(); |
||||
assertThat(delegate).isInstanceOf(Http2Client.class); |
||||
} |
||||
|
||||
@Test |
||||
void testFeignInheritanceSupport() { |
||||
assertThat(userClient).as("UserClient was null").isNotNull(); |
||||
final User user = userClient.getUser(1); |
||||
assertThat(user).as("Returned user was null").isNotNull(); |
||||
assertThat(new User("John Smith")).as("Users were different").isEqualTo(user); |
||||
} |
||||
|
||||
@FeignClient("localapp") |
||||
protected interface TestClient extends BaseTestClient { |
||||
|
||||
} |
||||
|
||||
protected interface BaseTestClient { |
||||
|
||||
@GetMapping("/hello") |
||||
Hello getHello(); |
||||
|
||||
@PatchMapping(value = "/hellop", consumes = "application/json") |
||||
ResponseEntity<Void> patchHello(Hello hello); |
||||
|
||||
} |
||||
|
||||
protected interface UserService { |
||||
|
||||
@GetMapping("/users/{id}") |
||||
User getUser(@PathVariable("id") long id); |
||||
|
||||
} |
||||
|
||||
@FeignClient("localapp1") |
||||
protected interface UserClient extends UserService { |
||||
|
||||
} |
||||
|
||||
@Configuration(proxyBeanMethods = false) |
||||
@EnableAutoConfiguration |
||||
@RestController |
||||
@EnableFeignClients(clients = { TestClient.class, UserClient.class }) |
||||
@LoadBalancerClients({ |
||||
@LoadBalancerClient(name = "localapp", configuration = FeignHttpClientTests.LocalClientConfiguration.class), |
||||
@LoadBalancerClient(name = "localapp1", |
||||
configuration = FeignHttpClientTests.LocalClientConfiguration.class) }) |
||||
@Import(NoSecurityConfiguration.class) |
||||
protected static class Application implements UserService { |
||||
|
||||
@GetMapping("/hello") |
||||
public Hello getHello() { |
||||
return new Hello("hello world 1"); |
||||
} |
||||
|
||||
@PatchMapping("/hellop") |
||||
public ResponseEntity<Void> patchHello(@RequestBody Hello hello, |
||||
@RequestHeader("Content-Length") int contentLength) { |
||||
if (contentLength <= 0) { |
||||
throw new IllegalArgumentException("Invalid Content-Length " + contentLength); |
||||
} |
||||
if (!hello.getMessage().equals("foo")) { |
||||
throw new IllegalArgumentException("Invalid Hello: " + hello.getMessage()); |
||||
} |
||||
return ResponseEntity.ok().header("X-Hello", "hello world patch").build(); |
||||
} |
||||
|
||||
@Override |
||||
public User getUser(@PathVariable("id") long id) { |
||||
return new User("John Smith"); |
||||
} |
||||
|
||||
} |
||||
|
||||
public static class Hello { |
||||
|
||||
private String message; |
||||
|
||||
Hello() { |
||||
} |
||||
|
||||
Hello(String message) { |
||||
this.message = message; |
||||
} |
||||
|
||||
public String getMessage() { |
||||
return message; |
||||
} |
||||
|
||||
public void setMessage(String message) { |
||||
this.message = message; |
||||
} |
||||
|
||||
@Override |
||||
public boolean equals(Object o) { |
||||
if (this == o) { |
||||
return true; |
||||
} |
||||
if (o == null || getClass() != o.getClass()) { |
||||
return false; |
||||
} |
||||
Hello that = (Hello) o; |
||||
return Objects.equals(message, that.message); |
||||
} |
||||
|
||||
@Override |
||||
public int hashCode() { |
||||
return Objects.hash(message); |
||||
} |
||||
|
||||
} |
||||
|
||||
public static class User { |
||||
|
||||
private String name; |
||||
|
||||
User() { |
||||
} |
||||
|
||||
User(String name) { |
||||
this.name = name; |
||||
} |
||||
|
||||
public String getName() { |
||||
return name; |
||||
} |
||||
|
||||
public void setName(String name) { |
||||
this.name = name; |
||||
} |
||||
|
||||
@Override |
||||
public boolean equals(Object o) { |
||||
if (this == o) { |
||||
return true; |
||||
} |
||||
if (o == null || getClass() != o.getClass()) { |
||||
return false; |
||||
} |
||||
User that = (User) o; |
||||
return Objects.equals(name, that.name); |
||||
} |
||||
|
||||
@Override |
||||
public int hashCode() { |
||||
return Objects.hash(name); |
||||
} |
||||
|
||||
} |
||||
|
||||
// Load balancer with fixed server list for "local" pointing to localhost
|
||||
@Configuration(proxyBeanMethods = false) |
||||
static class LocalClientConfiguration { |
||||
|
||||
@LocalServerPort |
||||
private int port = 0; |
||||
|
||||
@Bean |
||||
public ServiceInstanceListSupplier staticServiceInstanceListSupplier() { |
||||
return ServiceInstanceListSuppliers.from("local", |
||||
new DefaultServiceInstance("local-1", "local", "localhost", port, false)); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -1,11 +0,0 @@
@@ -1,11 +0,0 @@
|
||||
<configuration> |
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> |
||||
<encoder> |
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> |
||||
</encoder> |
||||
</appender> |
||||
|
||||
<root level="debug"> |
||||
<appender-ref ref="STDOUT" /> |
||||
</root> |
||||
</configuration> |
Loading…
Reference in new issue