├── .github
└── workflows
│ ├── maven-build.yml
│ └── maven-publish.yml
├── .gitignore
├── .mvn
└── wrapper
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── LICENSE
├── README.md
├── microsphere-spring-cloud-commons
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── io
│ │ │ └── microsphere
│ │ │ └── spring
│ │ │ └── cloud
│ │ │ ├── client
│ │ │ ├── condition
│ │ │ │ └── ConditionalOnFeaturesEnabled.java
│ │ │ ├── discovery
│ │ │ │ ├── UnionDiscoveryClient.java
│ │ │ │ ├── autoconfigure
│ │ │ │ │ └── DiscoveryClientAutoConfiguration.java
│ │ │ │ └── constants
│ │ │ │ │ └── DiscoveryClientConstants.java
│ │ │ ├── event
│ │ │ │ └── ServiceInstancesChangedEvent.java
│ │ │ └── service
│ │ │ │ ├── registry
│ │ │ │ ├── DefaultRegistration.java
│ │ │ │ ├── InMemoryServiceRegistry.java
│ │ │ │ ├── MultipleAutoServiceRegistration.java
│ │ │ │ ├── MultipleRegistration.java
│ │ │ │ ├── MultipleServiceRegistry.java
│ │ │ │ ├── RegistrationCustomizer.java
│ │ │ │ ├── RegistrationMetaData.java
│ │ │ │ ├── SimpleAutoServiceRegistration.java
│ │ │ │ ├── actuate
│ │ │ │ │ └── autoconfigure
│ │ │ │ │ │ └── ServiceRegistrationEndpointAutoConfiguration.java
│ │ │ │ ├── aspect
│ │ │ │ │ └── EventPublishingRegistrationAspect.java
│ │ │ │ ├── autoconfigure
│ │ │ │ │ ├── ServiceRegistryAutoConfiguration.java
│ │ │ │ │ ├── SimpleAutoServiceRegistrationAutoConfiguration.java
│ │ │ │ │ ├── WebFluxServiceRegistryAutoConfiguration.java
│ │ │ │ │ └── WebMvcServiceRegistryAutoConfiguration.java
│ │ │ │ ├── condition
│ │ │ │ │ ├── ConditionalOnAutoServiceRegistrationEnabled.java
│ │ │ │ │ └── ConditionalOnMultipleRegistrationEnabled.java
│ │ │ │ ├── constants
│ │ │ │ │ └── InstanceConstants.java
│ │ │ │ ├── endpoint
│ │ │ │ │ ├── AbstractServiceRegistrationEndpoint.java
│ │ │ │ │ ├── ServiceDeregistrationEndpoint.java
│ │ │ │ │ └── ServiceRegistrationEndpoint.java
│ │ │ │ └── event
│ │ │ │ │ ├── RegistrationDeregisteredEvent.java
│ │ │ │ │ ├── RegistrationEvent.java
│ │ │ │ │ ├── RegistrationPreDeregisteredEvent.java
│ │ │ │ │ ├── RegistrationPreRegisteredEvent.java
│ │ │ │ │ └── RegistrationRegisteredEvent.java
│ │ │ │ └── util
│ │ │ │ └── ServiceInstanceUtils.java
│ │ │ ├── commons
│ │ │ └── constants
│ │ │ │ └── CommonsPropertyConstants.java
│ │ │ └── fault
│ │ │ └── tolerance
│ │ │ ├── constants
│ │ │ └── FaultTolerancePropertyConstants.java
│ │ │ ├── loadbalancer
│ │ │ ├── WeightedRoundRobin.java
│ │ │ └── util
│ │ │ │ └── LoadBalancerUtils.java
│ │ │ └── tomcat
│ │ │ ├── autoconfigure
│ │ │ └── TomcatFaultToleranceAutoConfiguration.java
│ │ │ └── event
│ │ │ └── TomcatDynamicConfigurationListener.java
│ └── resources
│ │ └── META-INF
│ │ ├── config
│ │ └── default
│ │ │ └── endpoints.properties
│ │ ├── spring.factories
│ │ └── spring
│ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
│ └── test
│ ├── java
│ └── io
│ │ └── microsphere
│ │ └── spring
│ │ └── cloud
│ │ ├── client
│ │ ├── condition
│ │ │ └── ConditionalOnFeaturesEnabledTest.java
│ │ ├── discovery
│ │ │ ├── autoconfigure
│ │ │ │ ├── DiscoveryClientAutoConfigurationTest.java
│ │ │ │ └── UnionDiscoveryClientTest.java
│ │ │ └── constants
│ │ │ │ └── DiscoveryClientConstantsTest.java
│ │ ├── event
│ │ │ └── ServiceInstancesChangedEventTest.java
│ │ └── service
│ │ │ └── registry
│ │ │ ├── MultipleServiceRegistryTest.java
│ │ │ ├── actuate
│ │ │ └── autoconfigure
│ │ │ │ └── ServiceRegistrationEndpointAutoConfigurationTest.java
│ │ │ └── autoconfigure
│ │ │ ├── ServiceRegistryAutoConfigurationTest.java
│ │ │ ├── SimpleAutoServiceRegistrationAutoConfigurationTest.java
│ │ │ └── WebMvcServiceRegistryAutoConfigurationTest.java
│ │ ├── commons
│ │ └── constants
│ │ │ └── CommonsPropertyConstantsTest.java
│ │ └── fault
│ │ └── tolerance
│ │ └── tomcat
│ │ └── autoconfigure
│ │ └── TomcatFaultToleranceAutoConfigurationTest.java
│ └── resources
│ └── application.yaml
├── microsphere-spring-cloud-dependencies
└── pom.xml
├── microsphere-spring-cloud-openfeign
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── io
│ │ │ └── microsphere
│ │ │ └── spring
│ │ │ └── cloud
│ │ │ └── openfeign
│ │ │ ├── autoconfigure
│ │ │ ├── EnableFeignAutoRefresh.java
│ │ │ ├── FeignClientAutoRefreshAutoConfiguration.java
│ │ │ └── FeignClientSpecificationPostProcessor.java
│ │ │ ├── autorefresh
│ │ │ ├── AutoRefreshCapability.java
│ │ │ ├── FeignClientConfigurationChangedListener.java
│ │ │ └── FeignComponentRegistry.java
│ │ │ └── components
│ │ │ ├── CompositedRequestInterceptor.java
│ │ │ ├── DecoratedContract.java
│ │ │ ├── DecoratedDecoder.java
│ │ │ ├── DecoratedEncoder.java
│ │ │ ├── DecoratedErrorDecoder.java
│ │ │ ├── DecoratedFeignComponent.java
│ │ │ ├── DecoratedQueryMapEncoder.java
│ │ │ ├── DecoratedRetryer.java
│ │ │ ├── NoOpRequestInterceptor.java
│ │ │ └── Refreshable.java
│ └── resources
│ │ └── META-INF
│ │ └── spring
│ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
│ └── test
│ └── java
│ └── io
│ └── microsphere
│ └── spring
│ └── cloud
│ └── openfeign
│ ├── BaseClient.java
│ ├── BaseTest.java
│ ├── FeignComponentAssert.java
│ ├── MockCapability.java
│ ├── ObservableFeignInvocationHandler.java
│ ├── decoder
│ ├── ADecoder.java
│ ├── BDecoder.java
│ ├── DecoderChangedTest.java
│ └── DecoderComponentAssert.java
│ ├── encoder
│ ├── AEncoder.java
│ ├── BEncoder.java
│ ├── EncoderChangedTest.java
│ └── EncoderComponentAssert.java
│ ├── errordecoder
│ ├── AErrorDecoder.java
│ ├── BErrorEncoder.java
│ ├── ErrorDecoderChangedTest.java
│ └── ErrorDecoderComponentAssert.java
│ ├── querymapencoder
│ ├── AQueryMapEncoder.java
│ ├── BQueryMapEncoder.java
│ ├── QueryMapEncoderChangedTest.java
│ └── QueryMapEncoderComponentAssert.java
│ ├── requestInterceptor
│ ├── ARequestInterceptor.java
│ ├── BRequestInterceptor.java
│ ├── RequestInterceptorChangedTest.java
│ └── RequestInterceptorComponentAssert.java
│ └── retryer
│ ├── ARetry.java
│ ├── BRetry.java
│ ├── RetryerChangedTest.java
│ └── RetryerComponentAssert.java
├── microsphere-spring-cloud-parent
└── pom.xml
└── pom.xml
/.github/workflows/maven-build.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven
3 |
4 | # This workflow uses actions that are not certified by GitHub.
5 | # They are provided by a third-party and are governed by
6 | # separate terms of service, privacy policy, and support
7 | # documentation.
8 |
9 | name: Maven Build
10 |
11 | on:
12 | push:
13 | branches: [ 'dev' ]
14 | pull_request:
15 | branches: [ 'main', 'dev' , 'release' ]
16 |
17 | jobs:
18 | build:
19 | runs-on: ubuntu-latest
20 | strategy:
21 | matrix:
22 | java: [ '17' , '21' ]
23 | maven-profile-spring-cloud: [ 'spring-cloud-2022' , 'spring-cloud-2023' , 'spring-cloud-2024' ]
24 | steps:
25 | - name: Checkout Source
26 | uses: actions/checkout@v4
27 |
28 | - name: Setup JDK ${{ matrix.Java }}
29 | uses: actions/setup-java@v4
30 | with:
31 | distribution: 'temurin'
32 | java-version: ${{ matrix.java }}
33 | cache: maven
34 |
35 | - name: Build with Maven
36 | run: mvn
37 | --batch-mode
38 | --update-snapshots
39 | --file pom.xml
40 | -Drevision=0.0.1-SNAPSHOT
41 | test
42 | --activate-profiles test,coverage,${{ matrix.maven-profile-spring-cloud }}
43 |
44 | - name: Upload coverage reports to Codecov
45 | uses: codecov/codecov-action@v5
46 | with:
47 | token: ${{ secrets.CODECOV_TOKEN }}
48 | slug: microsphere-projects/microsphere-spring-cloud
--------------------------------------------------------------------------------
/.github/workflows/maven-publish.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven
3 |
4 | # This workflow uses actions that are not certified by GitHub.
5 | # They are provided by a third-party and are governed by
6 | # separate terms of service, privacy policy, and support
7 | # documentation.
8 |
9 | name: Maven Publish
10 |
11 | on:
12 | push:
13 | branches: [ 'release' ]
14 | workflow_dispatch:
15 | inputs:
16 | revision:
17 | description: 'The version to publish for Spring Cloud 2022+ and JDK 17+'
18 | required: true
19 | default: '2.0.0-SNAPSHOT'
20 |
21 | jobs:
22 | build:
23 | runs-on: ubuntu-latest
24 | if: ${{ inputs.revision }}
25 | steps:
26 | - name: Checkout Source
27 | uses: actions/checkout@v4
28 |
29 | - name: Setup Maven Central Repository
30 | uses: actions/setup-java@v4
31 | with:
32 | java-version: '17'
33 | distribution: 'temurin'
34 | server-id: ossrh
35 | server-username: MAVEN_USERNAME
36 | server-password: MAVEN_PASSWORD
37 | cache: maven
38 |
39 | - name: Publish package
40 | run: mvn
41 | --batch-mode
42 | --update-snapshots
43 | --file pom.xml
44 | -Drevision=${{ inputs.revision }}
45 | -Dgpg.skip=true
46 | deploy
47 | --activate-profiles release,ci
48 | env:
49 | MAVEN_USERNAME: ${{ secrets.OSS_SONATYPE_USERNAME }}
50 | MAVEN_PASSWORD: ${{ secrets.OSS_SONATYPE_PASSWORD }}
51 | SIGN_KEY_ID: ${{ secrets.OSS_SIGNING_KEY_ID_LONG }}
52 | SIGN_KEY: ${{ secrets.OSS_SIGNING_KEY }}
53 | SIGN_KEY_PASS: ${{ secrets.OSS_SIGNING_PASSWORD }}
54 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.nar
17 | *.ear
18 | *.zip
19 | *.tar.gz
20 | *.rar
21 |
22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
23 | hs_err_pid*
24 |
25 | # maven ignore
26 | target/
27 | !.mvn/wrapper/*
28 |
29 | # eclipse ignore
30 | .settings/
31 | .project
32 | .classpath
33 |
34 | # idea ignore
35 | .idea/
36 | .idea
37 | *.ipr
38 | *.iml
39 | *.iws
40 |
41 | # temp ignore
42 | *.log
43 | *.cache
44 | *.diff
45 | *.patch
46 | *.tmp
47 |
48 | # system ignore
49 | .DS_Store
50 | Thumbs.db
51 | *.orig
52 |
53 | # flatten ignore
54 | .flattened-pom.xml
55 |
56 | # license check result
57 | license-list
58 |
59 | # grpc compiler
60 | compiler/gradle.properties
61 | compiler/build/*
62 | compiler/.gradle/*
63 |
64 | # Tomcat
65 | .extract
66 | .java-version
67 |
68 | # others
69 | build.txt
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsphere-projects/microsphere-spring-cloud/6791f2abf86918c56b67f65a12c1fed595af279a/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | # Copyright 2013-2023 the original author or authors.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.0/apache-maven-3.9.0-bin.zip
16 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Microsphere Spring Cloud
2 |
3 | Microsphere Projects for Spring Cloud
4 |
5 | [](https://github.com/microsphere-projects/microsphere-spring-cloud/actions/workflows/maven-build.yml)
6 | [](https://app.codecov.io/gh/microsphere-projects/microsphere-spring-cloud)
7 | 
8 | 
9 | [](http://isitmaintained.com/project/microsphere-projects/microsphere-spring-cloud "Average time to resolve an issue")
10 | [](http://isitmaintained.com/project/microsphere-projects/microsphere-spring-cloud "Percentage of issues still open")
11 |
12 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | io.github.microsphere-projects
7 | microsphere-spring-cloud-parent
8 | ${revision}
9 | ../microsphere-spring-cloud-parent/pom.xml
10 |
11 | 4.0.0
12 |
13 | microsphere-spring-cloud-commons
14 | ${revision}
15 |
16 | Microsphere :: Spring Cloud :: Commons
17 | Microsphere Spring Cloud Commons
18 |
19 |
20 |
21 |
22 | org.aspectj
23 | aspectjweaver
24 |
25 |
26 |
27 |
28 | org.springframework.boot
29 | spring-boot-starter
30 | true
31 |
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter-web
36 | true
37 |
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-starter-webflux
42 | true
43 |
44 |
45 |
46 | org.springframework.boot
47 | spring-boot-configuration-processor
48 | true
49 |
50 |
51 |
52 | org.springframework.boot
53 | spring-boot-starter-actuator
54 | true
55 |
56 |
57 |
58 |
59 | org.springframework.cloud
60 | spring-cloud-commons
61 | true
62 |
63 |
64 |
65 | org.springframework.cloud
66 | spring-cloud-context
67 | true
68 |
69 |
70 |
71 |
72 | io.github.microsphere-projects
73 | microsphere-spring-boot-core
74 |
75 |
76 |
77 | io.github.microsphere-projects
78 | microsphere-spring-webmvc
79 | true
80 |
81 |
82 |
83 | io.github.microsphere-projects
84 | microsphere-spring-webflux
85 | true
86 |
87 |
88 |
89 |
90 | org.springframework.boot
91 | spring-boot-starter-test
92 | test
93 |
94 |
95 |
96 |
97 | org.testcontainers
98 | junit-jupiter
99 | test
100 |
101 |
102 |
103 |
104 | org.springframework.cloud
105 | spring-cloud-netflix-eureka-client
106 | test
107 |
108 |
109 |
110 | com.netflix.eureka
111 | eureka-client
112 | test
113 |
114 |
115 |
116 |
117 | com.alibaba.cloud
118 | spring-cloud-starter-alibaba-nacos-discovery
119 | test
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/condition/ConditionalOnFeaturesEnabled.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.condition;
18 |
19 | import io.microsphere.spring.cloud.commons.constants.CommonsPropertyConstants;
20 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
21 | import org.springframework.cloud.client.CommonsClientAutoConfiguration;
22 | import org.springframework.cloud.client.actuator.FeaturesEndpoint;
23 | import org.springframework.cloud.client.actuator.HasFeatures;
24 | import org.springframework.core.annotation.AliasFor;
25 |
26 | import java.lang.annotation.Documented;
27 | import java.lang.annotation.ElementType;
28 | import java.lang.annotation.Retention;
29 | import java.lang.annotation.RetentionPolicy;
30 | import java.lang.annotation.Target;
31 |
32 | import static io.microsphere.spring.cloud.commons.constants.CommonsPropertyConstants.FEATURES_ENABLED_PROPERTY_NAME;
33 |
34 | /**
35 | * The conditional annotation meta-annotates {@link ConditionalOnProperty @ConditionalOnProperty} for
36 | * {@link FeaturesEndpoint @FeaturesEndpoint} enabled.
37 | *
38 | * @author Mercy
39 | * @see CommonsClientAutoConfiguration.ActuatorConfiguration
40 | * @see FeaturesEndpoint
41 | * @see HasFeatures
42 | * @see CommonsPropertyConstants#FEATURES_ENABLED_PROPERTY_NAME
43 | * @see ConditionalOnProperty
44 | * @since 1.0.0
45 | */
46 | @Retention(RetentionPolicy.RUNTIME)
47 | @Target({ElementType.TYPE, ElementType.METHOD})
48 | @Documented
49 | @ConditionalOnProperty(name = FEATURES_ENABLED_PROPERTY_NAME)
50 | public @interface ConditionalOnFeaturesEnabled {
51 |
52 | /**
53 | * Specify if the condition should match if the property is not set. Defaults to
54 | * {@code true}.
55 | *
56 | * @return if the condition should match if the property is missing
57 | */
58 | @AliasFor(annotation = ConditionalOnProperty.class, attribute = "matchIfMissing")
59 | boolean matchIfMissing() default true;
60 | }
61 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/UnionDiscoveryClient.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.discovery;
18 |
19 | import org.springframework.beans.factory.DisposableBean;
20 | import org.springframework.beans.factory.ObjectProvider;
21 | import org.springframework.beans.factory.SmartInitializingSingleton;
22 | import org.springframework.cloud.client.ServiceInstance;
23 | import org.springframework.cloud.client.discovery.DiscoveryClient;
24 | import org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient;
25 |
26 | import java.util.ArrayList;
27 | import java.util.LinkedHashSet;
28 | import java.util.LinkedList;
29 | import java.util.List;
30 |
31 | import static io.microsphere.reflect.TypeUtils.getClassName;
32 | import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.COMPOSITE_DISCOVERY_CLIENT_CLASS_NAME;
33 |
34 | /**
35 | * The {@link DiscoveryClient} implementation for a union of the given {@link DiscoveryClient}
36 | *
37 | * @author Mercy
38 | * @see CompositeDiscoveryClient
39 | * @since 1.0.0
40 | */
41 | public final class UnionDiscoveryClient implements DiscoveryClient, SmartInitializingSingleton, DisposableBean {
42 |
43 | private final ObjectProvider discoveryClientsProvider;
44 |
45 | private List discoveryClients;
46 |
47 | public UnionDiscoveryClient(ObjectProvider discoveryClientsProvider) {
48 | this.discoveryClientsProvider = discoveryClientsProvider;
49 | }
50 |
51 | @Override
52 | public String description() {
53 | return "Union Discovery Client";
54 | }
55 |
56 | @Override
57 | public List getInstances(String serviceId) {
58 | List serviceInstances = new LinkedList<>();
59 | List discoveryClients = getDiscoveryClients();
60 | for (DiscoveryClient discoveryClient : discoveryClients) {
61 | List instances = discoveryClient.getInstances(serviceId);
62 | if (instances != null && !instances.isEmpty()) {
63 | serviceInstances.addAll(instances);
64 | }
65 | }
66 | return serviceInstances;
67 | }
68 |
69 | @Override
70 | public List getServices() {
71 | LinkedHashSet services = new LinkedHashSet<>();
72 | List discoveryClients = getDiscoveryClients();
73 | for (DiscoveryClient discoveryClient : discoveryClients) {
74 | List serviceForClient = discoveryClient.getServices();
75 | if (serviceForClient != null) {
76 | services.addAll(serviceForClient);
77 | }
78 | }
79 | return new ArrayList<>(services);
80 | }
81 |
82 | public List getDiscoveryClients() {
83 | List discoveryClients = this.discoveryClients;
84 | if (discoveryClients != null) {
85 | return discoveryClients;
86 | }
87 |
88 | discoveryClients = new LinkedList<>();
89 |
90 | for (DiscoveryClient discoveryClient : discoveryClientsProvider) {
91 | String className = getClassName(discoveryClient.getClass());
92 | if (COMPOSITE_DISCOVERY_CLIENT_CLASS_NAME.equals(className) || this.equals(discoveryClient)) {
93 | // excludes CompositeDiscoveryClient and self
94 | continue;
95 | }
96 | discoveryClients.add(discoveryClient);
97 | }
98 | return discoveryClients;
99 | }
100 |
101 | @Override
102 | public int getOrder() {
103 | return HIGHEST_PRECEDENCE;
104 | }
105 |
106 | @Override
107 | public void afterSingletonsInstantiated() {
108 | this.discoveryClients = getDiscoveryClients();
109 | }
110 |
111 | @Override
112 | public void destroy() throws Exception {
113 | this.discoveryClients.clear();
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/autoconfigure/DiscoveryClientAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.discovery.autoconfigure;
18 |
19 | import io.microsphere.spring.cloud.client.discovery.UnionDiscoveryClient;
20 | import org.springframework.beans.factory.ObjectProvider;
21 | import org.springframework.boot.autoconfigure.AutoConfigureBefore;
22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
23 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
24 | import org.springframework.cloud.client.CommonsClientAutoConfiguration;
25 | import org.springframework.cloud.client.ConditionalOnBlockingDiscoveryEnabled;
26 | import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled;
27 | import org.springframework.cloud.client.discovery.DiscoveryClient;
28 | import org.springframework.context.annotation.Bean;
29 | import org.springframework.context.annotation.Configuration;
30 |
31 | import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.COMMONS_CLIENT_AUTO_CONFIGURATION_CLASS_NAME;
32 | import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.DISCOVERY_CLIENT_CLASS_NAME;
33 | import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.DISCOVERY_CLIENT_PROPERTY_PREFIX;
34 | import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.MODE_PROPERTY_NAME;
35 | import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.UNION_DISCOVERY_CLIENT_MODE;
36 |
37 | /**
38 | * {@link UnionDiscoveryClient} Auto-Configuration Class
39 | *
40 | * @author Mercy
41 | * @see UnionDiscoveryClient
42 | * @see CommonsClientAutoConfiguration
43 | * @since 1.0.0
44 | */
45 | @Configuration(proxyBeanMethods = false)
46 | @ConditionalOnClass(name = {
47 | DISCOVERY_CLIENT_CLASS_NAME
48 | })
49 | @ConditionalOnDiscoveryEnabled
50 | @ConditionalOnBlockingDiscoveryEnabled
51 | @AutoConfigureBefore(name = {
52 | COMMONS_CLIENT_AUTO_CONFIGURATION_CLASS_NAME
53 | })
54 | public class DiscoveryClientAutoConfiguration {
55 |
56 | @Configuration(proxyBeanMethods = false)
57 | @ConditionalOnProperty(prefix = DISCOVERY_CLIENT_PROPERTY_PREFIX, name = MODE_PROPERTY_NAME, havingValue = UNION_DISCOVERY_CLIENT_MODE)
58 | public static class UnionConfiguration {
59 |
60 | @Bean
61 | public UnionDiscoveryClient unionDiscoveryClient(ObjectProvider discoveryClientsProvider) {
62 | return new UnionDiscoveryClient(discoveryClientsProvider);
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/constants/DiscoveryClientConstants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.discovery.constants;
18 |
19 | import io.microsphere.spring.cloud.client.discovery.UnionDiscoveryClient;
20 | import org.springframework.cloud.client.CommonsClientAutoConfiguration;
21 | import org.springframework.cloud.client.discovery.DiscoveryClient;
22 | import org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient;
23 |
24 | import static io.microsphere.spring.cloud.commons.constants.CommonsPropertyConstants.MICROSPHERE_SPRING_CLOUD_PROPERTY_NAME_PREFIX;
25 |
26 | /**
27 | * The constants for {@link DiscoveryClient}
28 | *
29 | * @author Mercy
30 | * @since 1.0.0
31 | */
32 | public interface DiscoveryClientConstants {
33 |
34 | /**
35 | * The property prefix of {@link DiscoveryClient} : "microsphere.spring.cloud.client.discovery."
36 | */
37 | String DISCOVERY_CLIENT_PROPERTY_PREFIX = MICROSPHERE_SPRING_CLOUD_PROPERTY_NAME_PREFIX + "client.discovery.";
38 |
39 | /**
40 | * The property name of mode : "mode"
41 | */
42 | String MODE_PROPERTY_NAME = "mode";
43 |
44 | /**
45 | * The {@link DiscoveryClient} "mode" for {@link UnionDiscoveryClient} : "union"
46 | */
47 | String UNION_DISCOVERY_CLIENT_MODE = "union";
48 |
49 | /**
50 | * The class name of {@link DiscoveryClient}
51 | */
52 | String DISCOVERY_CLIENT_CLASS_NAME = "org.springframework.cloud.client.discovery.DiscoveryClient";
53 |
54 | /**
55 | * The class name of {@link CompositeDiscoveryClient}
56 | */
57 | String COMPOSITE_DISCOVERY_CLIENT_CLASS_NAME = "org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient";
58 |
59 | /**
60 | * The class name of {@link CommonsClientAutoConfiguration}
61 | */
62 | String COMMONS_CLIENT_AUTO_CONFIGURATION_CLASS_NAME = "org.springframework.cloud.client.CommonsClientAutoConfiguration";
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/event/ServiceInstancesChangedEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.event;
18 |
19 | import org.springframework.cloud.client.ServiceInstance;
20 | import org.springframework.context.ApplicationEvent;
21 | import org.springframework.context.event.ApplicationEventMulticaster;
22 | import org.springframework.context.event.SimpleApplicationEventMulticaster;
23 |
24 | import java.util.List;
25 |
26 | import static java.util.Collections.unmodifiableList;
27 | import static org.springframework.util.Assert.notEmpty;
28 |
29 | /**
30 | * An event raised when the {@link ServiceInstance instances} of one service has been
31 | * changed.
32 | *
33 | * @author Mercy
34 | */
35 | public class ServiceInstancesChangedEvent extends ApplicationEvent {
36 |
37 | private final List serviceInstances;
38 |
39 | /**
40 | * Current event has been processed or not. Typically, Spring Event was based on sync
41 | * {@link ApplicationEventMulticaster}
42 | *
43 | * @see SimpleApplicationEventMulticaster
44 | */
45 | private boolean processed = false;
46 |
47 | /**
48 | * @param serviceName The name of service that was changed
49 | * @param serviceInstances all {@link ServiceInstance service instances}
50 | * @throws IllegalArgumentException if source is null.
51 | */
52 | public ServiceInstancesChangedEvent(String serviceName,
53 | List serviceInstances) {
54 | super(serviceName);
55 | notEmpty(serviceInstances, () -> "The arguments 'serviceInstances' must not be empty!");
56 | this.serviceInstances = unmodifiableList(serviceInstances);
57 | }
58 |
59 | /**
60 | * @return The name of service that was changed
61 | */
62 | public String getServiceName() {
63 | return (String) getSource();
64 | }
65 |
66 | /**
67 | * @return all {@link ServiceInstance service instances}.
68 | */
69 | public List getServiceInstances() {
70 | return serviceInstances;
71 | }
72 |
73 | /**
74 | * Mark current event being processed.
75 | */
76 | public void processed() {
77 | processed = true;
78 | }
79 |
80 | /**
81 | * Current event has been processed or not.
82 | *
83 | * @return if processed, return true
, or false
84 | */
85 | public boolean isProcessed() {
86 | return processed;
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/DefaultRegistration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.service.registry;
18 |
19 | import org.springframework.cloud.client.DefaultServiceInstance;
20 | import org.springframework.cloud.client.serviceregistry.Registration;
21 |
22 | /**
23 | * Default {@link Registration}
24 | *
25 | * @author Mercy
26 | * @see DefaultServiceInstance
27 | * @since 1.0.0
28 | */
29 | public class DefaultRegistration extends DefaultServiceInstance implements Registration {
30 | }
31 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/InMemoryServiceRegistry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.service.registry;
18 |
19 | import org.springframework.cloud.client.serviceregistry.Registration;
20 | import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
21 |
22 | import java.util.Map;
23 | import java.util.concurrent.ConcurrentHashMap;
24 | import java.util.concurrent.ConcurrentMap;
25 |
26 | /**
27 | * In-Memory {@link ServiceRegistry}
28 | *
29 | * @author Mercy
30 | * @since 1.0.0
31 | */
32 | public class InMemoryServiceRegistry implements ServiceRegistry {
33 |
34 | private static final String STATUS_KEY = "_status_";
35 |
36 | private final ConcurrentMap storage = new ConcurrentHashMap<>(1);
37 |
38 | @Override
39 | public void register(Registration registration) {
40 | String id = registration.getInstanceId();
41 | storage.put(id, registration);
42 | }
43 |
44 | @Override
45 | public void deregister(Registration registration) {
46 | String id = registration.getInstanceId();
47 | storage.remove(id, registration);
48 | }
49 |
50 | @Override
51 | public void close() {
52 | storage.clear();
53 | }
54 |
55 | @Override
56 | public void setStatus(Registration registration, String status) {
57 | Map metadata = getMetadata(registration);
58 | if (metadata != null) {
59 | metadata.put(STATUS_KEY, status);
60 | }
61 | }
62 |
63 | @Override
64 | public Object getStatus(Registration registration) {
65 | Map metadata = getMetadata(registration);
66 | if (metadata != null) {
67 | return metadata.get(STATUS_KEY);
68 | }
69 | return null;
70 | }
71 |
72 | protected Map getMetadata(Registration registration) {
73 | String id = registration.getInstanceId();
74 | Registration instance = storage.get(id);
75 | if (storage != null) {
76 | return instance.getMetadata();
77 | }
78 | return null;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/MultipleAutoServiceRegistration.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.client.service.registry;
2 |
3 | import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration;
4 | import org.springframework.cloud.client.serviceregistry.AutoServiceRegistration;
5 | import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
6 | import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
7 |
8 | /**
9 | * {@link AutoServiceRegistration} for the multiple service registration
10 | *
11 | * @author 韩超
12 | * @author Mercy
13 | * @see AutoServiceRegistration
14 | * @see MultipleRegistration
15 | * @since 1.0.0
16 | */
17 | public class MultipleAutoServiceRegistration extends AbstractAutoServiceRegistration {
18 |
19 | private final AutoServiceRegistrationProperties autoServiceRegistrationProperties;
20 | private final MultipleRegistration multipleRegistration;
21 |
22 | public MultipleAutoServiceRegistration(MultipleRegistration multipleRegistration,
23 | ServiceRegistry serviceRegistry,
24 | AutoServiceRegistrationProperties properties) {
25 | super(serviceRegistry, properties);
26 | this.autoServiceRegistrationProperties = properties;
27 | this.multipleRegistration = multipleRegistration;
28 | }
29 |
30 | @Override
31 | protected Object getConfiguration() {
32 | return null;
33 | }
34 |
35 | @Override
36 | protected boolean isEnabled() {
37 | return this.autoServiceRegistrationProperties.isEnabled();
38 | }
39 |
40 | @Override
41 | protected MultipleRegistration getRegistration() {
42 | return this.multipleRegistration;
43 | }
44 |
45 | @Override
46 | protected MultipleRegistration getManagementRegistration() {
47 | return this.multipleRegistration;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/MultipleRegistration.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.client.service.registry;
2 |
3 | import org.springframework.cloud.client.serviceregistry.Registration;
4 | import org.springframework.util.CollectionUtils;
5 |
6 | import java.net.URI;
7 | import java.util.Collection;
8 | import java.util.HashMap;
9 | import java.util.Map;
10 |
11 | /**
12 | * The Delegating {@link Registration} for the multiple service registration
13 | *
14 | * @author 韩超
15 | * @see MultipleAutoServiceRegistration
16 | * @see MultipleServiceRegistry
17 | * @since 1.0.0
18 | */
19 | public class MultipleRegistration implements Registration {
20 |
21 | private Map, Registration> registrationMap = new HashMap<>();
22 |
23 | private Registration defaultRegistration;
24 |
25 | private final RegistrationMetaData metaData;
26 |
27 | public MultipleRegistration(Collection registrations) {
28 | if (CollectionUtils.isEmpty(registrations))
29 | throw new IllegalArgumentException("registrations cannot be empty");
30 | //init map
31 | for (Registration registration : registrations) {
32 | Class extends Registration> clazz = registration.getClass();
33 | this.registrationMap.put(clazz, registration);
34 | this.defaultRegistration = registration;
35 | }
36 | this.metaData = new RegistrationMetaData(registrations);
37 | }
38 |
39 | @Override
40 | public String getServiceId() {
41 | return getDefaultRegistration().getServiceId();
42 | }
43 |
44 | @Override
45 | public String getHost() {
46 | return getDefaultRegistration().getHost();
47 | }
48 |
49 | @Override
50 | public int getPort() {
51 | return getDefaultRegistration().getPort();
52 | }
53 |
54 | @Override
55 | public boolean isSecure() {
56 | return getDefaultRegistration().isSecure();
57 | }
58 |
59 | @Override
60 | public URI getUri() {
61 | return getDefaultRegistration().getUri();
62 | }
63 |
64 | @Override
65 | public Map getMetadata() {
66 | return metaData;
67 | }
68 |
69 | public Registration getDefaultRegistration() {
70 | return defaultRegistration;
71 | }
72 |
73 | public T special(Class specialClass) {
74 | if (specialClass.equals(Registration.class))
75 | return (T) this;
76 | return (T) this.registrationMap.getOrDefault(specialClass, null);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/RegistrationCustomizer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.service.registry;
18 |
19 | import org.springframework.cloud.client.serviceregistry.Registration;
20 |
21 | /**
22 | * {@link Registration} Customizer
23 | *
24 | * @author Mercy
25 | * @see Registration
26 | * @since 1.0.0
27 | */
28 | public interface RegistrationCustomizer {
29 |
30 | /**
31 | * Customize the specified {@link Registration} before register
32 | *
33 | * @param registration {@link Registration}
34 | */
35 | void customize(Registration registration);
36 | }
37 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/RegistrationMetaData.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.client.service.registry;
2 |
3 | import org.springframework.cloud.client.serviceregistry.Registration;
4 | import org.springframework.util.CollectionUtils;
5 |
6 | import java.util.Collection;
7 | import java.util.Collections;
8 | import java.util.Map;
9 | import java.util.Set;
10 | import java.util.concurrent.ConcurrentHashMap;
11 |
12 | /**
13 | * @author 韩超
14 | * @since 1.0.0
15 | */
16 | public final class RegistrationMetaData implements Map {
17 |
18 | /**
19 | * MetaData information manually added by the application,usually specified by configuration
20 | */
21 | private final Map applicationMetaData;
22 | private final Collection registrations;
23 | private final Object lock = new Object();
24 |
25 | public RegistrationMetaData(Collection registrations) {
26 | if (CollectionUtils.isEmpty(registrations))
27 | throw new IllegalArgumentException("registrations cannot be empty");
28 |
29 | this.registrations = registrations;
30 | this.applicationMetaData = new ConcurrentHashMap<>();
31 | for (Registration registration : registrations) {
32 | Map metaData = registration.getMetadata();
33 | if (!CollectionUtils.isEmpty(metaData)) {
34 | //check key and value must not be null
35 | metaData.forEach((k, v) -> {
36 | if (k == null || v == null)
37 | return;
38 | this.applicationMetaData.put(k, v);
39 | });
40 | }
41 | }
42 | }
43 |
44 | @Override
45 | public int size() {
46 | return applicationMetaData.size();
47 | }
48 |
49 | @Override
50 | public boolean isEmpty() {
51 | return this.applicationMetaData.isEmpty();
52 | }
53 |
54 | @Override
55 | public boolean containsKey(Object key) {
56 | return this.applicationMetaData.containsKey(key);
57 | }
58 |
59 | @Override
60 | public boolean containsValue(Object value) {
61 | return this.applicationMetaData.containsValue(value);
62 | }
63 |
64 | @Override
65 | public String get(Object key) {
66 | return this.applicationMetaData.get(key);
67 | }
68 |
69 | @Override
70 | public String put(String key, String value) {
71 | synchronized (lock) {
72 | this.registrations.forEach(registration -> {
73 | registration.getMetadata().put(key, value);
74 | });
75 | }
76 | return this.applicationMetaData.put(key, value);
77 | }
78 |
79 | @Override
80 | public String remove(Object key) {
81 | synchronized (lock) {
82 | this.registrations.forEach(registration -> {
83 | registration.getMetadata().remove(key);
84 | });
85 | }
86 | return this.applicationMetaData.remove(key);
87 | }
88 |
89 | @Override
90 | public void putAll(Map extends String, ? extends String> m) {
91 | synchronized (lock) {
92 | this.registrations.forEach(registration -> {
93 | registration.getMetadata().putAll(m);
94 | });
95 | }
96 | this.applicationMetaData.putAll(m);
97 | }
98 |
99 | @Override
100 | public void clear() {
101 | synchronized (lock) {
102 | this.registrations.forEach(registration -> registration.getMetadata().clear());
103 | }
104 | this.applicationMetaData.clear();
105 | }
106 |
107 | @Override
108 | public Set keySet() {
109 | return Collections.unmodifiableSet(this.applicationMetaData.keySet());
110 | }
111 |
112 | @Override
113 | public Collection values() {
114 | return Collections.unmodifiableCollection(this.applicationMetaData.values());
115 | }
116 |
117 | @Override
118 | public Set> entrySet() {
119 | return this.applicationMetaData.entrySet();
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/SimpleAutoServiceRegistration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.service.registry;
18 |
19 | import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration;
20 | import org.springframework.cloud.client.serviceregistry.AutoServiceRegistration;
21 | import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
22 | import org.springframework.cloud.client.serviceregistry.Registration;
23 | import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
24 |
25 | /**
26 | * Default {@link AutoServiceRegistration}
27 | *
28 | * @author Mercy
29 | * @since 1.0.0
30 | */
31 | public class SimpleAutoServiceRegistration extends AbstractAutoServiceRegistration {
32 |
33 | private final AutoServiceRegistrationProperties properties;
34 |
35 | private final Registration registration;
36 |
37 | protected SimpleAutoServiceRegistration(ServiceRegistry serviceRegistry,
38 | AutoServiceRegistrationProperties properties, Registration registration) {
39 | super(serviceRegistry, properties);
40 | this.properties = properties;
41 | this.registration = registration;
42 | }
43 |
44 | @Override
45 | protected Object getConfiguration() {
46 | return properties;
47 | }
48 |
49 | @Override
50 | protected boolean isEnabled() {
51 | return properties.isEnabled();
52 | }
53 |
54 | @Override
55 | protected Registration getRegistration() {
56 | return registration;
57 | }
58 |
59 | @Override
60 | protected Registration getManagementRegistration() {
61 | return registration;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/actuate/autoconfigure/ServiceRegistrationEndpointAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.service.registry.actuate.autoconfigure;
18 |
19 | import io.microsphere.spring.cloud.client.service.registry.condition.ConditionalOnAutoServiceRegistrationEnabled;
20 | import io.microsphere.spring.cloud.client.service.registry.endpoint.ServiceDeregistrationEndpoint;
21 | import io.microsphere.spring.cloud.client.service.registry.endpoint.ServiceRegistrationEndpoint;
22 | import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
23 | import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
24 | import org.springframework.boot.autoconfigure.AutoConfigureAfter;
25 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
26 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
27 | import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled;
28 | import org.springframework.context.annotation.Bean;
29 |
30 | /**
31 | * Microsphere {@link Endpoint @Endpoints} Auto-Configuration for Service Registration
32 | *
33 | * @author Mercy
34 | * @see Endpoint
35 | * @since 1.0.0
36 | */
37 | @ConditionalOnDiscoveryEnabled
38 | @ConditionalOnClass(name = {
39 | "org.springframework.boot.actuate.endpoint.annotation.Endpoint",
40 | "org.springframework.cloud.client.serviceregistry.AutoServiceRegistration"
41 | })
42 | @ConditionalOnAutoServiceRegistrationEnabled
43 | @AutoConfigureAfter(name = {
44 | "org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration",
45 | "org.springframework.cloud.zookeeper.serviceregistry.ZookeeperServiceRegistryAutoConfiguration",
46 | "org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistryAutoConfiguration",
47 | "org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryClientAutoConfiguration",
48 | "com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration",
49 | })
50 | public class ServiceRegistrationEndpointAutoConfiguration {
51 |
52 | @Bean
53 | @ConditionalOnMissingBean
54 | @ConditionalOnAvailableEndpoint
55 | public ServiceRegistrationEndpoint serviceRegistrationEndpoint() {
56 | return new ServiceRegistrationEndpoint();
57 | }
58 |
59 | @Bean
60 | @ConditionalOnMissingBean
61 | @ConditionalOnAvailableEndpoint
62 | public ServiceDeregistrationEndpoint serviceDeregistrationEndpoint() {
63 | return new ServiceDeregistrationEndpoint();
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/aspect/EventPublishingRegistrationAspect.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.service.registry.aspect;
18 |
19 | import io.microsphere.spring.cloud.client.service.registry.MultipleServiceRegistry;
20 | import io.microsphere.spring.cloud.client.service.registry.RegistrationCustomizer;
21 | import io.microsphere.spring.cloud.client.service.registry.event.RegistrationDeregisteredEvent;
22 | import io.microsphere.spring.cloud.client.service.registry.event.RegistrationPreDeregisteredEvent;
23 | import io.microsphere.spring.cloud.client.service.registry.event.RegistrationPreRegisteredEvent;
24 | import io.microsphere.spring.cloud.client.service.registry.event.RegistrationRegisteredEvent;
25 | import org.aspectj.lang.annotation.After;
26 | import org.aspectj.lang.annotation.Aspect;
27 | import org.aspectj.lang.annotation.Before;
28 | import org.springframework.beans.BeansException;
29 | import org.springframework.beans.factory.ObjectProvider;
30 | import org.springframework.cloud.client.serviceregistry.Registration;
31 | import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
32 | import org.springframework.context.ApplicationContext;
33 | import org.springframework.context.ApplicationContextAware;
34 |
35 | /**
36 | * Event-Publishing Aspect for {@link Registration}.
37 | *
38 | * @author Mercy
39 | * @see RegistrationPreRegisteredEvent
40 | * @see RegistrationRegisteredEvent
41 | * @see RegistrationPreDeregisteredEvent
42 | * @see RegistrationDeregisteredEvent
43 | * @since 1.0.0
44 | */
45 | @Aspect
46 | public class EventPublishingRegistrationAspect implements ApplicationContextAware {
47 |
48 | /**
49 | * The pointcut expression for {@link ServiceRegistry#register(Registration)}.
50 | */
51 | public static final String REGISTER_POINTCUT_EXPRESSION = "execution(* org.springframework.cloud.client.serviceregistry.ServiceRegistry.register(*)) && target(registry) && args(registration)";
52 |
53 | /**
54 | * The pointcut expression for {@link ServiceRegistry#deregister(Registration)}.
55 | */
56 | public static final String DEREGISTER_POINTCUT_EXPRESSION = "execution(* org.springframework.cloud.client.serviceregistry.ServiceRegistry.deregister(*)) && target(registry) && args(registration)";
57 |
58 | private ApplicationContext context;
59 |
60 | private ObjectProvider registrationCustomizers;
61 |
62 | @Before(value = REGISTER_POINTCUT_EXPRESSION, argNames = "registry, registration")
63 | public void beforeRegister(ServiceRegistry registry, Registration registration) {
64 | if (registry.getClass().isAssignableFrom(MultipleServiceRegistry.class))
65 | return;//Remove redundant register
66 | context.publishEvent(new RegistrationPreRegisteredEvent(registry, registration));
67 | registrationCustomizers.forEach(customizer -> {
68 | customizer.customize(registration);
69 | });
70 | }
71 |
72 | @Before(value = DEREGISTER_POINTCUT_EXPRESSION, argNames = "registry, registration")
73 | public void beforeDeregister(ServiceRegistry registry, Registration registration) {
74 | if (registry.getClass().isAssignableFrom(MultipleServiceRegistry.class))
75 | return;//Remove redundant deregister
76 | context.publishEvent(new RegistrationPreDeregisteredEvent(registry, registration));
77 | }
78 |
79 | @After(value = REGISTER_POINTCUT_EXPRESSION, argNames = "registry, registration")
80 | public void afterRegister(ServiceRegistry registry, Registration registration) {
81 | if (registry.getClass().isAssignableFrom(MultipleServiceRegistry.class))
82 | return;//Remove redundant register
83 | context.publishEvent(new RegistrationRegisteredEvent(registry, registration));
84 | }
85 |
86 | @After(value = DEREGISTER_POINTCUT_EXPRESSION, argNames = "registry, registration")
87 | public void afterDeregister(ServiceRegistry registry, Registration registration) {
88 | if (registry.getClass().isAssignableFrom(MultipleServiceRegistry.class))
89 | return;//Remove redundant deregister
90 | context.publishEvent(new RegistrationDeregisteredEvent(registry, registration));
91 | }
92 |
93 | @Override
94 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
95 | this.context = applicationContext;
96 | this.registrationCustomizers = applicationContext.getBeanProvider(RegistrationCustomizer.class);
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/ServiceRegistryAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.service.registry.autoconfigure;
18 |
19 | import io.microsphere.spring.cloud.client.service.registry.MultipleAutoServiceRegistration;
20 | import io.microsphere.spring.cloud.client.service.registry.MultipleRegistration;
21 | import io.microsphere.spring.cloud.client.service.registry.MultipleServiceRegistry;
22 | import io.microsphere.spring.cloud.client.service.registry.aspect.EventPublishingRegistrationAspect;
23 | import io.microsphere.spring.cloud.client.service.registry.condition.ConditionalOnAutoServiceRegistrationEnabled;
24 | import io.microsphere.spring.cloud.client.service.registry.condition.ConditionalOnMultipleRegistrationEnabled;
25 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
26 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
27 | import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
28 | import org.springframework.cloud.client.serviceregistry.Registration;
29 | import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
30 | import org.springframework.context.annotation.Bean;
31 | import org.springframework.context.annotation.Configuration;
32 | import org.springframework.context.annotation.Import;
33 | import org.springframework.context.annotation.Primary;
34 |
35 | import java.util.Collection;
36 | import java.util.Map;
37 |
38 | /**
39 | * Auto-Configuration class for {@link ServiceRegistry ServiceRegistry}
40 | *
41 | * @author Mercy
42 | * @since 1.0.0
43 | */
44 | @Configuration(proxyBeanMethods = false)
45 | @ConditionalOnAutoServiceRegistrationEnabled
46 | @Import(value = {
47 | EventPublishingRegistrationAspect.class,
48 | ServiceRegistryAutoConfiguration.MultipleConfiguration.class
49 | })
50 | public class ServiceRegistryAutoConfiguration {
51 |
52 | /**
53 | * The configuration class of the multiple service registration
54 | */
55 | @ConditionalOnMultipleRegistrationEnabled
56 | static class MultipleConfiguration {
57 |
58 | @Primary
59 | @Bean
60 | @ConditionalOnMissingBean
61 | public MultipleRegistration multipleRegistration(Collection registrations) {
62 | return new MultipleRegistration(registrations);
63 | }
64 |
65 | @Bean
66 | @Primary
67 | @ConditionalOnMissingBean
68 | public MultipleServiceRegistry multipleServiceRegistry(Map registriesMap) {
69 | return new MultipleServiceRegistry(registriesMap);
70 | }
71 |
72 | @ConditionalOnBean(AutoServiceRegistrationProperties.class)
73 | @Primary
74 | @Bean
75 | @ConditionalOnMissingBean
76 | public MultipleAutoServiceRegistration multipleAutoServiceRegistration(MultipleRegistration multipleRegistration,
77 | MultipleServiceRegistry multipleServiceRegistry,
78 | AutoServiceRegistrationProperties properties) {
79 | return new MultipleAutoServiceRegistration(multipleRegistration, multipleServiceRegistry, properties);
80 | }
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/SimpleAutoServiceRegistrationAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.service.registry.autoconfigure;
18 |
19 | import io.microsphere.spring.cloud.client.service.registry.DefaultRegistration;
20 | import io.microsphere.spring.cloud.client.service.registry.InMemoryServiceRegistry;
21 | import io.microsphere.spring.cloud.client.service.registry.SimpleAutoServiceRegistration;
22 | import io.microsphere.spring.cloud.client.service.registry.condition.ConditionalOnAutoServiceRegistrationEnabled;
23 | import org.springframework.beans.factory.annotation.Value;
24 | import org.springframework.boot.autoconfigure.AutoConfigureAfter;
25 | import org.springframework.boot.autoconfigure.AutoConfigureBefore;
26 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
27 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
28 | import org.springframework.boot.autoconfigure.web.ServerProperties;
29 | import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration;
30 | import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration;
31 | import org.springframework.cloud.client.serviceregistry.Registration;
32 | import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
33 | import org.springframework.cloud.commons.util.InetUtils;
34 | import org.springframework.cloud.commons.util.UtilAutoConfiguration;
35 | import org.springframework.context.annotation.Bean;
36 | import org.springframework.context.annotation.Configuration;
37 | import org.springframework.context.annotation.Import;
38 |
39 | import static io.microsphere.constants.PropertyConstants.ENABLED_PROPERTY_NAME;
40 | import static io.microsphere.spring.cloud.client.service.registry.autoconfigure.SimpleAutoServiceRegistrationAutoConfiguration.PROPERTY_NAME_PREFIX;
41 | import static io.microsphere.spring.cloud.commons.constants.CommonsPropertyConstants.MICROSPHERE_SPRING_CLOUD_PROPERTY_NAME_PREFIX;
42 |
43 | /**
44 | * Auto-Configuration class for {@link SimpleAutoServiceRegistration}
45 | *
46 | * @author Mercy
47 | * @see SimpleAutoServiceRegistration
48 | * @since 1.0.0
49 | */
50 | @Configuration(proxyBeanMethods = false)
51 | @ConditionalOnProperty(prefix = PROPERTY_NAME_PREFIX, name = ENABLED_PROPERTY_NAME)
52 | @ConditionalOnAutoServiceRegistrationEnabled
53 | @AutoConfigureBefore(value = {
54 | AutoServiceRegistrationAutoConfiguration.class
55 | })
56 | @AutoConfigureAfter(value = {
57 | UtilAutoConfiguration.class,
58 | AutoServiceRegistrationConfiguration.class
59 | })
60 | @Import(value = {
61 | SimpleAutoServiceRegistration.class
62 | })
63 | public class SimpleAutoServiceRegistrationAutoConfiguration {
64 |
65 | /**
66 | * The property name prefix : "microsphere.spring.cloud.service-registry.auto-registration.simple."
67 | */
68 | public static final String PROPERTY_NAME_PREFIX = MICROSPHERE_SPRING_CLOUD_PROPERTY_NAME_PREFIX + "service-registry.auto-registration.simple.";
69 |
70 | @Bean
71 | public Registration registration(
72 | @Value("${spring.application.name:default}") String applicationName,
73 | ServerProperties serverProperties,
74 | InetUtils inetUtils
75 | ) {
76 | InetUtils.HostInfo hostInfo = inetUtils.findFirstNonLoopbackHostInfo();
77 | String host = hostInfo.getIpAddress();
78 | int port = serverProperties.getPort();
79 | String instanceId = host + ":" + port;
80 | DefaultRegistration registration = new DefaultRegistration();
81 | registration.setInstanceId(instanceId);
82 | registration.setServiceId(applicationName);
83 | registration.setHost(host);
84 | registration.setPort(serverProperties.getPort());
85 | return registration;
86 | }
87 |
88 | @Bean
89 | @ConditionalOnMissingBean
90 | public ServiceRegistry serviceRegistry() {
91 | return new InMemoryServiceRegistry();
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/WebFluxServiceRegistryAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.service.registry.autoconfigure;
18 |
19 | import io.microsphere.spring.cloud.client.service.registry.condition.ConditionalOnAutoServiceRegistrationEnabled;
20 | import org.springframework.boot.autoconfigure.AutoConfigureAfter;
21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
23 | import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
24 | import org.springframework.context.annotation.Configuration;
25 |
26 | import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type.REACTIVE;
27 |
28 | /**
29 | * Auto-Configuration class for {@link ServiceRegistry ServiceRegistry} on the Spring WebFlux Application
30 | *
31 | * @author Mercy
32 | * @since 1.0.0
33 | */
34 | @Configuration(proxyBeanMethods = false)
35 | @ConditionalOnClass(name = {
36 | "io.microsphere.spring.web.metadata.WebEndpointMapping",
37 | "io.microsphere.spring.web.event.WebEndpointMappingsReadyEvent"
38 | })
39 | @ConditionalOnWebApplication(type = REACTIVE)
40 | @ConditionalOnAutoServiceRegistrationEnabled
41 | @AutoConfigureAfter(value = {
42 | ServiceRegistryAutoConfiguration.class
43 | })
44 | public class WebFluxServiceRegistryAutoConfiguration {
45 | }
46 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/condition/ConditionalOnAutoServiceRegistrationEnabled.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.service.registry.condition;
18 |
19 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
20 | import org.springframework.cloud.client.serviceregistry.AutoServiceRegistration;
21 | import org.springframework.core.annotation.AliasFor;
22 |
23 | import java.lang.annotation.Documented;
24 | import java.lang.annotation.ElementType;
25 | import java.lang.annotation.Retention;
26 | import java.lang.annotation.RetentionPolicy;
27 | import java.lang.annotation.Target;
28 |
29 | import static io.microsphere.spring.cloud.commons.constants.CommonsPropertyConstants.SERVICE_REGISTRY_AUTO_REGISTRATION_ENABLED_PROPERTY_NAME;
30 |
31 | /**
32 | * The conditional annotation meta-annotates {@link ConditionalOnProperty @ConditionalOnProperty} for
33 | * {@link AutoServiceRegistration Service Registry Auto-Registration} enabled.
34 | *
35 | * @author Mercy
36 | * @see AutoServiceRegistration
37 | * @see ConditionalOnProperty
38 | * @since 1.0.0
39 | */
40 | @Retention(RetentionPolicy.RUNTIME)
41 | @Target({ElementType.TYPE, ElementType.METHOD})
42 | @Documented
43 | @ConditionalOnProperty(name = SERVICE_REGISTRY_AUTO_REGISTRATION_ENABLED_PROPERTY_NAME)
44 | public @interface ConditionalOnAutoServiceRegistrationEnabled {
45 |
46 | /**
47 | * Specify if the condition should match if the property is not set. Defaults to
48 | * {@code true}.
49 | *
50 | * @return if the condition should match if the property is missing
51 | */
52 | @AliasFor(annotation = ConditionalOnProperty.class, attribute = "matchIfMissing")
53 | boolean matchIfMissing() default true;
54 | }
55 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/condition/ConditionalOnMultipleRegistrationEnabled.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.client.service.registry.condition;
2 |
3 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
4 | import org.springframework.context.annotation.Conditional;
5 |
6 | import java.lang.annotation.Documented;
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 |
12 | import static io.microsphere.spring.cloud.commons.constants.CommonsPropertyConstants.MULTIPLE_REGISTRATION_ENABLED_PROPERTY_NAME;
13 |
14 | /**
15 | * {@link Conditional @Conditional} that checks whether the multiple service registry enabled
16 | *
17 | * @author 韩超
18 | * @author Mercy
19 | * @since 1.0
20 | */
21 | @Retention(RetentionPolicy.RUNTIME)
22 | @Target({ElementType.TYPE, ElementType.METHOD})
23 | @Documented
24 | @ConditionalOnProperty(name = MULTIPLE_REGISTRATION_ENABLED_PROPERTY_NAME)
25 | public @interface ConditionalOnMultipleRegistrationEnabled {
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/constants/InstanceConstants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.service.registry.constants;
18 |
19 | /**
20 | * The constants for Service Instance
21 | *
22 | * @author Mercy
23 | * @since 1.0.0
24 | */
25 | public interface InstanceConstants {
26 |
27 | /**
28 | * The meta-data name of Web Mappings
29 | */
30 | String WEB_MAPPINGS_METADATA_NAME = "web.mappings";
31 |
32 | /**
33 | * The meta-data name of Web Context Path
34 | */
35 | String WEB_CONTEXT_PATH_METADATA_NAME = "web.context-path";
36 | }
37 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/endpoint/AbstractServiceRegistrationEndpoint.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.client.service.registry.endpoint;
2 |
3 | import org.springframework.beans.factory.ObjectProvider;
4 | import org.springframework.beans.factory.SmartInitializingSingleton;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.beans.factory.annotation.Value;
7 | import org.springframework.boot.web.context.WebServerInitializedEvent;
8 | import org.springframework.boot.web.server.WebServer;
9 | import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration;
10 | import org.springframework.cloud.client.serviceregistry.Registration;
11 | import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
12 | import org.springframework.context.ApplicationListener;
13 |
14 | /**
15 | * Abstract Endpoint for Service Registration
16 | *
17 | * @author Mercy
18 | * @since 1.0.0
19 | */
20 | public class AbstractServiceRegistrationEndpoint implements SmartInitializingSingleton, ApplicationListener {
21 |
22 | @Value("${spring.application.name}")
23 | protected String applicationName;
24 |
25 | @Autowired
26 | private ObjectProvider registrationProvider;
27 |
28 | @Autowired
29 | private ObjectProvider serviceRegistryProvider;
30 |
31 | @Autowired
32 | private ObjectProvider autoServiceRegistrationProvider;
33 |
34 | protected Registration registration;
35 |
36 | protected ServiceRegistry serviceRegistry;
37 |
38 | protected AbstractAutoServiceRegistration serviceRegistration;
39 |
40 | protected int port;
41 |
42 | protected static boolean running;
43 |
44 | @Override
45 | public void afterSingletonsInstantiated() {
46 | this.registration = registrationProvider.getIfAvailable();
47 | this.serviceRegistry = serviceRegistryProvider.getIfAvailable();
48 | this.serviceRegistration = autoServiceRegistrationProvider.getIfAvailable();
49 | }
50 |
51 | @Override
52 | public void onApplicationEvent(WebServerInitializedEvent event) {
53 | WebServer webServer = event.getWebServer();
54 | this.port = webServer.getPort();
55 | this.running = serviceRegistration == null ? true : serviceRegistration.isRunning();
56 | }
57 |
58 | protected boolean isRunning() {
59 | return running;
60 | }
61 |
62 | public void setRunning(boolean running) {
63 | this.running = running;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/endpoint/ServiceDeregistrationEndpoint.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.client.service.registry.endpoint;
2 |
3 | import io.microsphere.logging.Logger;
4 | import io.microsphere.logging.LoggerFactory;
5 | import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
6 | import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
7 | import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration;
8 |
9 | /**
10 | * The {@link Endpoint @Endpoint} for Service Deregistration
11 | *
12 | * @author Mercy
13 | * @see AbstractAutoServiceRegistration
14 | * @see Endpoint
15 | * @since 1.0.0
16 | */
17 | @Endpoint(id = "serviceDeregistration")
18 | public class ServiceDeregistrationEndpoint extends AbstractServiceRegistrationEndpoint {
19 |
20 | private final Logger logger = LoggerFactory.getLogger(getClass());
21 |
22 | @WriteOperation
23 | public boolean stop() {
24 | boolean isRunning = isRunning();
25 | if (isRunning) {
26 | serviceRegistry.deregister(registration);
27 | if(logger.isInfoEnabled()) {
28 | logger.info("Service[name : '{}'] is deregistered!", applicationName);
29 | }
30 | setRunning(false);
31 | } else {
32 | if (logger.isWarnEnabled()) {
33 | logger.warn("Service[name : '{}'] is not registered, deregistration can't be executed!", applicationName);
34 | }
35 | }
36 | return isRunning;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/endpoint/ServiceRegistrationEndpoint.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.client.service.registry.endpoint;
2 |
3 | import io.microsphere.logging.Logger;
4 | import io.microsphere.logging.LoggerFactory;
5 | import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
6 | import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
7 | import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
8 | import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration;
9 | import org.springframework.util.ReflectionUtils;
10 |
11 | import java.lang.reflect.Method;
12 | import java.util.LinkedHashMap;
13 | import java.util.Map;
14 |
15 | /**
16 | * The {@link Endpoint @Endpoint} for Service Registration
17 | *
18 | * @author Mercy
19 | * @see AbstractAutoServiceRegistration
20 | * @see Endpoint
21 | * @since 1.0.0
22 | */
23 | @Endpoint(id = "serviceRegistration")
24 | public class ServiceRegistrationEndpoint extends AbstractServiceRegistrationEndpoint {
25 |
26 | private final Logger logger = LoggerFactory.getLogger(getClass());
27 |
28 | @ReadOperation
29 | public Map metadata() {
30 |
31 | Map metadata = new LinkedHashMap<>();
32 |
33 | metadata.put("application-name", applicationName);
34 | metadata.put("registration", registration);
35 | metadata.put("port", port);
36 | metadata.put("status", serviceRegistry.getStatus(registration));
37 | metadata.put("running", isRunning());
38 |
39 | if (serviceRegistration != null) {
40 | metadata.put("enabled", invoke("isEnabled"));
41 | metadata.put("phase", serviceRegistration.getPhase());
42 | metadata.put("order", serviceRegistration.getOrder());
43 | if (Boolean.TRUE.equals(invoke("shouldRegisterManagement"))) {
44 | metadata.put("managementRegistration", invoke("getManagementRegistration"));
45 | }
46 | metadata.put("config", invoke("getConfiguration"));
47 | }
48 |
49 | return metadata;
50 | }
51 |
52 | @WriteOperation
53 | public boolean start() {
54 | boolean isRunning = isRunning();
55 | if (!isRunning) {
56 | serviceRegistry.register(registration);
57 | setRunning(true);
58 | if(logger.isTraceEnabled()) {
59 | logger.trace("Service[name : '{}'] is registered!", applicationName);
60 | }
61 | } else {
62 | if(logger.isWarnEnabled()) {
63 | logger.warn("Service[name : '{}'] was registered!", applicationName);
64 | }
65 | }
66 | return isRunning;
67 | }
68 |
69 | private Object invoke(String methodName) {
70 | Object returnValue = null;
71 | try {
72 | Class> serviceRegistrationClass = AbstractAutoServiceRegistration.class;
73 | Method method = serviceRegistrationClass.getDeclaredMethod(methodName);
74 | ReflectionUtils.makeAccessible(method);
75 | returnValue = method.invoke(serviceRegistration);
76 | } catch (Throwable e) {
77 | logger.error("Invocation on method :" + methodName + "is failed", e);
78 | }
79 | return returnValue;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationDeregisteredEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.service.registry.event;
18 |
19 | import org.springframework.cloud.client.serviceregistry.Registration;
20 | import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
21 |
22 | import static io.microsphere.spring.cloud.client.service.registry.event.RegistrationEvent.Type.DEREGISTERED;
23 |
24 | /**
25 | * The after-{@link ServiceRegistry#deregister(Registration) deregister} event.
26 | *
27 | * @author Mercy
28 | * @see ServiceRegistry
29 | * @since 1.0.0
30 | */
31 | public class RegistrationDeregisteredEvent extends RegistrationEvent {
32 |
33 | public RegistrationDeregisteredEvent(ServiceRegistry registry, Registration source) {
34 | super(registry, source);
35 | }
36 |
37 | @Override
38 | public Type getType() {
39 | return DEREGISTERED;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationPreDeregisteredEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.service.registry.event;
18 |
19 | import org.springframework.cloud.client.serviceregistry.Registration;
20 | import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
21 |
22 | import static io.microsphere.spring.cloud.client.service.registry.event.RegistrationEvent.Type.PRE_DEREGISTERED;
23 |
24 | /**
25 | * The before-{@link ServiceRegistry#deregister(Registration) deregister} event.
26 | *
27 | * @author Mercy
28 | * @see ServiceRegistry
29 | * @since 1.0.0
30 | */
31 | public class RegistrationPreDeregisteredEvent extends RegistrationEvent {
32 |
33 | public RegistrationPreDeregisteredEvent(ServiceRegistry registry, Registration source) {
34 | super(registry, source);
35 | }
36 |
37 | @Override
38 | public Type getType() {
39 | return PRE_DEREGISTERED;
40 | }
41 | }
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationPreRegisteredEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.service.registry.event;
18 |
19 | import org.springframework.cloud.client.serviceregistry.Registration;
20 | import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
21 |
22 | import static io.microsphere.spring.cloud.client.service.registry.event.RegistrationEvent.Type.PRE_REGISTERED;
23 |
24 | /**
25 | * The before-{@link ServiceRegistry#register(Registration) register} event.
26 | *
27 | * @author Mercy
28 | * @see ServiceRegistry
29 | * @since 1.0.0
30 | */
31 | public class RegistrationPreRegisteredEvent extends RegistrationEvent {
32 |
33 | public RegistrationPreRegisteredEvent(ServiceRegistry registry, Registration source) {
34 | super(registry, source);
35 | }
36 |
37 | @Override
38 | public Type getType() {
39 | return PRE_REGISTERED;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationRegisteredEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.service.registry.event;
18 |
19 | import org.springframework.cloud.client.serviceregistry.Registration;
20 | import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
21 |
22 | import static io.microsphere.spring.cloud.client.service.registry.event.RegistrationEvent.Type.REGISTERED;
23 |
24 | /**
25 | * The after-{@link ServiceRegistry#register(Registration) register} event.
26 | *
27 | * @author Mercy
28 | * @see ServiceRegistry
29 | * @since 1.0.0
30 | */
31 | public class RegistrationRegisteredEvent extends RegistrationEvent {
32 |
33 | public RegistrationRegisteredEvent(ServiceRegistry registry, Registration source) {
34 | super(registry, source);
35 | }
36 |
37 | @Override
38 | public Type getType() {
39 | return REGISTERED;
40 | }
41 | }
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/util/ServiceInstanceUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.service.util;
18 |
19 | import com.fasterxml.jackson.core.type.TypeReference;
20 | import com.fasterxml.jackson.databind.ObjectMapper;
21 | import io.microsphere.logging.Logger;
22 | import io.microsphere.logging.LoggerFactory;
23 | import io.microsphere.spring.web.metadata.WebEndpointMapping;
24 | import io.microsphere.util.BaseUtils;
25 | import org.springframework.cloud.client.ServiceInstance;
26 |
27 | import java.util.Collection;
28 | import java.util.Collections;
29 | import java.util.List;
30 | import java.util.Map;
31 | import java.util.StringJoiner;
32 |
33 | import static io.microsphere.net.URLUtils.decode;
34 | import static io.microsphere.net.URLUtils.encode;
35 | import static io.microsphere.spring.cloud.client.service.registry.constants.InstanceConstants.WEB_CONTEXT_PATH_METADATA_NAME;
36 | import static io.microsphere.spring.cloud.client.service.registry.constants.InstanceConstants.WEB_MAPPINGS_METADATA_NAME;
37 |
38 | /**
39 | * {@link ServiceInstance} Utilities class
40 | *
41 | * @author Mercy
42 | * @since 1.0.0
43 | */
44 | public class ServiceInstanceUtils extends BaseUtils {
45 |
46 | private static final Logger logger = LoggerFactory.getLogger(ServiceInstanceUtils.class);
47 |
48 | public static void attachMetadata(String contextPath, ServiceInstance serviceInstance, Collection webEndpointMappings) {
49 | Map metadata = serviceInstance.getMetadata();
50 | StringJoiner jsonBuilder = new StringJoiner(",", "[", "]");
51 | webEndpointMappings.stream().map(WebEndpointMapping::toJSON).forEach(jsonBuilder::add);
52 | String json = jsonBuilder.toString();
53 | metadata.put(WEB_CONTEXT_PATH_METADATA_NAME, contextPath);
54 | try {
55 | String encodedJson = encode(json);
56 | metadata.put(WEB_MAPPINGS_METADATA_NAME, encodedJson);
57 | } catch (IllegalArgumentException e) {
58 | logger.error("The JSON content of WebEndpointMappings can't be encoded : {}", json, e);
59 | }
60 | }
61 |
62 | public static Collection getWebEndpointMappings(ServiceInstance serviceInstance) {
63 | List webEndpointMappings = Collections.emptyList();
64 | Map metadata = serviceInstance.getMetadata();
65 | String encodedJSON = metadata.get(WEB_MAPPINGS_METADATA_NAME);
66 | if (encodedJSON != null) {
67 | try {
68 | String json = decode(encodedJSON);
69 | ObjectMapper objectMapper = new ObjectMapper();
70 | webEndpointMappings = objectMapper.readValue(json, new TypeReference>() {
71 | });
72 | } catch (Throwable e) {
73 | logger.error("The encoded JSON content of WebEndpointMappings can't be parsed : {}", encodedJSON, e);
74 | }
75 | }
76 | return webEndpointMappings;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/commons/constants/CommonsPropertyConstants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.commons.constants;
18 |
19 | import org.springframework.cloud.client.CommonsClientAutoConfiguration;
20 | import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration;
21 |
22 | import static io.microsphere.constants.PropertyConstants.ENABLED_PROPERTY_NAME;
23 | import static io.microsphere.constants.PropertyConstants.MICROSPHERE_PROPERTY_NAME_PREFIX;
24 |
25 | /**
26 | * The property constants for Spring Cloud Commons
27 | *
28 | * @author Mercy
29 | * @since 1.0.0
30 | */
31 | public interface CommonsPropertyConstants {
32 |
33 | /**
34 | * The property name prefix of Spring Cloud properties : "spring.cloud."
35 | */
36 | String SPRING_CLOUD_PROPERTY_PREFIX = "spring.cloud.";
37 |
38 | /**
39 | * The property name prefix of Spring Cloud Service Registry : "spring.cloud.service-registry."
40 | */
41 | String SERVICE_REGISTRY_PROPERTY_PREFIX = SPRING_CLOUD_PROPERTY_PREFIX + "service-registry.";
42 |
43 | /**
44 | * The property name for Spring Cloud Service Registry Auto-Registration Feature :
45 | * "spring.cloud.service-registry.auto-registration.enabled"
46 | *
47 | * @see AutoServiceRegistrationAutoConfiguration
48 | */
49 | String SERVICE_REGISTRY_AUTO_REGISTRATION_ENABLED_PROPERTY_NAME = SERVICE_REGISTRY_PROPERTY_PREFIX + "auto-registration." + ENABLED_PROPERTY_NAME;
50 |
51 | /**
52 | * The property name for enabling Spring Cloud Features : "spring.cloud.features.enabled"
53 | *
54 | * @see CommonsClientAutoConfiguration.ActuatorConfiguration
55 | */
56 | String FEATURES_ENABLED_PROPERTY_NAME = SPRING_CLOUD_PROPERTY_PREFIX + "features." + ENABLED_PROPERTY_NAME;
57 |
58 | /**
59 | * The property name prefix of Microsphere Cloud : "microsphere.spring.cloud."
60 | */
61 | String MICROSPHERE_SPRING_CLOUD_PROPERTY_NAME_PREFIX = MICROSPHERE_PROPERTY_NAME_PREFIX + SPRING_CLOUD_PROPERTY_PREFIX;
62 |
63 | /**
64 | * The property name prefix of Microsphere Cloud Web MVC : "microsphere.spring.cloud.web.mvc."
65 | */
66 | String MICROSPHERE_SPRING_CLOUD_WEB_MVC_PROPERTY_NAME_PREFIX = MICROSPHERE_SPRING_CLOUD_PROPERTY_NAME_PREFIX + "web.mvc.";
67 |
68 | /**
69 | * The property name for Multiple Service Registry Enabled Feature : "microsphere.spring.cloud.multiple-registration.enabled"
70 | */
71 | String MULTIPLE_REGISTRATION_ENABLED_PROPERTY_NAME = MICROSPHERE_SPRING_CLOUD_PROPERTY_NAME_PREFIX + "multiple-registration." + ENABLED_PROPERTY_NAME;
72 |
73 | /**
74 | * The property name for Default Service Registry Type : "microsphere.spring.cloud.default-registration.type"
75 | */
76 | String MULTIPLE_REGISTRATION_DEFAULT_REGISTRATION_PROPERTY_NAME = MICROSPHERE_SPRING_CLOUD_PROPERTY_NAME_PREFIX + "default-registration.type";
77 |
78 | /**
79 | * The property name for Default Service Registry Type : "microsphere.spring.cloud.default-service-registry.type"
80 | */
81 | String MULTIPLE_REGISTRATION_DEFAULT_REGISTRY_PROPERTY_NAME = MICROSPHERE_SPRING_CLOUD_PROPERTY_NAME_PREFIX + "default-service-registry.type";
82 |
83 | /**
84 | * The property name for Composite Service Registry Enabled Feature : "microsphere.spring.cloud.composite-registration.enabled"
85 | */
86 | String COMPOSITE_REGISTRATION_ENABLED_PROPERTY_NAME = MICROSPHERE_SPRING_CLOUD_PROPERTY_NAME_PREFIX + "composite-registration." + ENABLED_PROPERTY_NAME;
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/fault/tolerance/constants/FaultTolerancePropertyConstants.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.fault.tolerance.constants;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | import static io.microsphere.spring.cloud.commons.constants.CommonsPropertyConstants.MICROSPHERE_SPRING_CLOUD_PROPERTY_NAME_PREFIX;
6 |
7 | /**
8 | * Fault-Tolerance Property Constants
9 | *
10 | * @author Mercy
11 | * @since 1.0.0
12 | */
13 | public interface FaultTolerancePropertyConstants {
14 |
15 | /**
16 | * Property name prefix
17 | */
18 | String FAULT_TOLERANCE_PROPERTY_NAME_PREFIX = MICROSPHERE_SPRING_CLOUD_PROPERTY_NAME_PREFIX + "fault-tolerance.";
19 |
20 | /**
21 | * Load Balancers' property name prefix
22 | */
23 | String LOAD_BALANCER_PROPERTY_PREFIX = FAULT_TOLERANCE_PROPERTY_NAME_PREFIX + "load-balancer.";
24 |
25 | /**
26 | * The metadata name of management
27 | */
28 | String MANAGEMENT_PORT_METADATA_NAME = "management-port";
29 |
30 | /**
31 | * The metadata name of start time
32 | */
33 | String START_TIME_METADATA_NAME = "start-time";
34 |
35 | /**
36 | * The metadata name of warm-up time
37 | */
38 | String WARMUP_TIME_PROPERTY_NAME = FAULT_TOLERANCE_PROPERTY_NAME_PREFIX + "warmup-time";
39 |
40 | /**
41 | * The property name of weight
42 | */
43 | String WEIGHT_PROPERTY_NAME = FAULT_TOLERANCE_PROPERTY_NAME_PREFIX + "weight";
44 |
45 | /**
46 | * The default property value of warm-up time :10 minutes
47 | */
48 | long DEFAULT_WARMUP_TIME_PROPERTY_VALUE = TimeUnit.MINUTES.toMillis(10);
49 |
50 | /**
51 | * The default property value of weight : 100
52 | */
53 | int DEFAULT_WEIGHT_PROPERTY_VALUE = 100;
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/fault/tolerance/loadbalancer/WeightedRoundRobin.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.fault.tolerance.loadbalancer;
2 |
3 | import java.util.StringJoiner;
4 | import java.util.concurrent.atomic.LongAdder;
5 |
6 | /**
7 | * Weighed Round-Robin
8 | *
9 | * @author Mercy
10 | * @since 1.0.0
11 | */
12 | public class WeightedRoundRobin {
13 |
14 | private final String id;
15 |
16 | private volatile int weight;
17 |
18 | private LongAdder current = new LongAdder();
19 |
20 | private volatile long lastUpdate;
21 |
22 | public WeightedRoundRobin(String id) {
23 | this.id = id;
24 | }
25 |
26 | public String getId() {
27 | return id;
28 | }
29 |
30 | public int getWeight() {
31 | return weight;
32 | }
33 |
34 | public void setWeight(int weight) {
35 | this.weight = weight;
36 | current.reset();
37 | }
38 |
39 | public long increaseCurrent() {
40 | current.add(weight);
41 | return current.longValue();
42 | }
43 |
44 | public void sel(int total) {
45 | current.add(-1 * total);
46 | }
47 |
48 | public long getLastUpdate() {
49 | return lastUpdate;
50 | }
51 |
52 | public void setLastUpdate(long lastUpdate) {
53 | this.lastUpdate = lastUpdate;
54 | }
55 |
56 | @Override
57 | public String toString() {
58 | return new StringJoiner(", ", WeightedRoundRobin.class.getSimpleName() + "[", "]")
59 | .add("id='" + id + "'")
60 | .add("weight=" + weight)
61 | .add("current=" + current)
62 | .add("lastUpdate=" + lastUpdate)
63 | .toString();
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/fault/tolerance/loadbalancer/util/LoadBalancerUtils.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.fault.tolerance.loadbalancer.util;
2 |
3 | /**
4 | * The utilities class of Load Balancer
5 | *
6 | * @author Mercy
7 | * @since 1.0.0
8 | */
9 | public abstract class LoadBalancerUtils {
10 |
11 | private LoadBalancerUtils() {
12 | throw new UnsupportedOperationException();
13 | }
14 |
15 | /**
16 | * Calculate the weight according to the uptime proportion of warmup time
17 | * the new weight will be within 1(inclusive) to weight(inclusive)
18 | *
19 | * @param uptime the uptime in milliseconds
20 | * @param warmup the warmup time in milliseconds
21 | * @param weight the weight of an invoker
22 | * @return weight which takes warmup into account
23 | */
24 | public static int calculateWarmupWeight(long uptime, long warmup, int weight) {
25 | int ww = (int) (Math.round(Math.pow((uptime / (double) warmup), 2) * weight));
26 | return ww < 1 ? 1 : (Math.min(ww, weight));
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/fault/tolerance/tomcat/autoconfigure/TomcatFaultToleranceAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.fault.tolerance.tomcat.autoconfigure;
18 |
19 | import io.microsphere.spring.cloud.fault.tolerance.constants.FaultTolerancePropertyConstants;
20 | import io.microsphere.spring.cloud.fault.tolerance.tomcat.event.TomcatDynamicConfigurationListener;
21 | import org.apache.catalina.startup.Tomcat;
22 | import org.springframework.beans.factory.ObjectProvider;
23 | import org.springframework.boot.autoconfigure.AutoConfigureAfter;
24 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
25 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
26 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
27 | import org.springframework.boot.autoconfigure.web.ServerProperties;
28 | import org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration;
29 | import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext;
30 | import org.springframework.boot.web.context.WebServerApplicationContext;
31 | import org.springframework.boot.web.context.WebServerInitializedEvent;
32 | import org.springframework.boot.web.embedded.tomcat.TomcatWebServer;
33 | import org.springframework.boot.web.server.WebServer;
34 | import org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration;
35 | import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
36 | import org.springframework.context.event.EventListener;
37 |
38 | import static io.microsphere.constants.PropertyConstants.ENABLED_PROPERTY_NAME;
39 | import static io.microsphere.spring.cloud.fault.tolerance.tomcat.autoconfigure.TomcatFaultToleranceAutoConfiguration.TOMCAT_PROPERTY_PREFIX;
40 | import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type.SERVLET;
41 |
42 | /**
43 | * @author Mercy
44 | * @since 1.0.0
45 | */
46 | @ConditionalOnProperty(
47 | prefix = TOMCAT_PROPERTY_PREFIX,
48 | name = ENABLED_PROPERTY_NAME,
49 | matchIfMissing = true
50 | )
51 | @ConditionalOnClass(value = {
52 | EnvironmentChangeEvent.class,
53 | Tomcat.class
54 | })
55 | @ConditionalOnWebApplication(type = SERVLET)
56 | @AutoConfigureAfter(value = {
57 | EmbeddedWebServerFactoryCustomizerAutoConfiguration.class,
58 | ConfigurationPropertiesRebinderAutoConfiguration.class
59 | })
60 | public class TomcatFaultToleranceAutoConfiguration {
61 |
62 | public static final String TOMCAT_PROPERTY_PREFIX = FaultTolerancePropertyConstants.FAULT_TOLERANCE_PROPERTY_NAME_PREFIX + "tomcat";
63 |
64 | @EventListener(WebServerInitializedEvent.class)
65 | public void onWebServerInitializedEvent(WebServerInitializedEvent event) {
66 | WebServerApplicationContext webServerApplicationContext = event.getApplicationContext();
67 | if (webServerApplicationContext instanceof ConfigurableWebServerApplicationContext) {
68 | ConfigurableWebServerApplicationContext context = (ConfigurableWebServerApplicationContext) webServerApplicationContext;
69 | ObjectProvider beanProvider = context.getBeanProvider(ServerProperties.class);
70 |
71 | beanProvider.ifAvailable(serverProperties -> {
72 | WebServer webServer = event.getWebServer();
73 | if (webServer instanceof TomcatWebServer) {
74 | TomcatWebServer tomcatWebServer = (TomcatWebServer) webServer;
75 | context.addApplicationListener(new TomcatDynamicConfigurationListener(tomcatWebServer, serverProperties, context));
76 | }
77 | });
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/resources/META-INF/config/default/endpoints.properties:
--------------------------------------------------------------------------------
1 | # Spring Cloud Actuator Endpoints Default Properties
2 |
3 | ### Spring Cloud Endpoints
4 | management.endpoint.archaius.enabled = false
5 | management.endpoint.refresh.enabled = false
6 | management.endpoint.restart.enabled = false
7 | management.endpoint.pause.enabled = false
8 | management.endpoint.resume.enabled = false
9 | management.endpoint.features.enabled = false
10 | management.endpoint.service-registry.enabled = false
11 |
12 | ### Spring Cloud Env
13 | management.endpoint.env.post.enabled = false
14 |
15 | ## Microsphere Endpoints
16 | management.endpoint.serviceRegistration.enabled = false
17 | management.endpoint.serviceDeregistration.enabled = false
18 |
19 | ## Endpoint Web Path Mapping
20 | management.endpoints.web.path-mapping.serviceRegistration = microsphere/service/registration
21 | management.endpoints.web.path-mapping.serviceDeregistration = microsphere/service/deregistration
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/resources/META-INF/spring.factories:
--------------------------------------------------------------------------------
1 | com.alibaba.cloud.nacos.registry.NacosServiceRegistry = com.alibaba.cloud.nacos.registry.NacosRegistration
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports:
--------------------------------------------------------------------------------
1 | io.microsphere.spring.cloud.client.discovery.autoconfigure.DiscoveryClientAutoConfiguration
2 | io.microsphere.spring.cloud.client.service.registry.autoconfigure.ServiceRegistryAutoConfiguration
3 | io.microsphere.spring.cloud.client.service.registry.autoconfigure.WebMvcServiceRegistryAutoConfiguration
4 | io.microsphere.spring.cloud.client.service.registry.autoconfigure.WebFluxServiceRegistryAutoConfiguration
5 | io.microsphere.spring.cloud.client.service.registry.autoconfigure.SimpleAutoServiceRegistrationAutoConfiguration
6 | io.microsphere.spring.cloud.client.service.registry.actuate.autoconfigure.ServiceRegistrationEndpointAutoConfiguration
7 | io.microsphere.spring.cloud.fault.tolerance.tomcat.autoconfigure.TomcatFaultToleranceAutoConfiguration
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/condition/ConditionalOnFeaturesEnabledTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.condition;
18 |
19 | /**
20 | * {@link ConditionalOnFeaturesEnabled} Test
21 | *
22 | * @author Mercy
23 | * @see ConditionalOnFeaturesEnabled
24 | * @since 1.0.0
25 | */
26 |
27 | import org.junit.jupiter.api.Test;
28 | import org.junit.jupiter.api.extension.ExtendWith;
29 | import org.springframework.beans.factory.ObjectProvider;
30 | import org.springframework.beans.factory.annotation.Autowired;
31 | import org.springframework.test.context.ContextConfiguration;
32 | import org.springframework.test.context.TestPropertySource;
33 | import org.springframework.test.context.junit.jupiter.SpringExtension;
34 |
35 | import static org.junit.jupiter.api.Assertions.assertNotNull;
36 |
37 | @ExtendWith(SpringExtension.class)
38 | @ContextConfiguration(classes = {
39 | ConditionalOnFeaturesEnabledTest.FeaturesConfiguration.class
40 | })
41 | @TestPropertySource(
42 | properties = {
43 | "spring.cloud.features.enabled=true"
44 | }
45 | )
46 | public class ConditionalOnFeaturesEnabledTest {
47 |
48 | @ConditionalOnFeaturesEnabled
49 | static class FeaturesConfiguration {
50 | }
51 |
52 | @Autowired
53 | private ObjectProvider featuresConfigurationProvider;
54 |
55 | @Test
56 | public void test() {
57 | assertNotNull(featuresConfigurationProvider.getIfAvailable());
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/discovery/autoconfigure/DiscoveryClientAutoConfigurationTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.discovery.autoconfigure;
18 |
19 | import io.microsphere.spring.cloud.client.discovery.UnionDiscoveryClient;
20 | import io.microsphere.spring.cloud.client.discovery.UnionDiscoveryClientTest;
21 | import org.junit.jupiter.api.Test;
22 | import org.junit.jupiter.api.extension.ExtendWith;
23 | import org.springframework.beans.factory.annotation.Autowired;
24 | import org.springframework.boot.test.context.SpringBootTest;
25 | import org.springframework.cloud.client.discovery.DiscoveryClient;
26 | import org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient;
27 | import org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration;
28 | import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClient;
29 | import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration;
30 | import org.springframework.cloud.commons.util.UtilAutoConfiguration;
31 | import org.springframework.test.context.TestPropertySource;
32 | import org.springframework.test.context.junit.jupiter.SpringExtension;
33 |
34 | import java.util.Arrays;
35 | import java.util.List;
36 |
37 | import static org.junit.jupiter.api.Assertions.assertEquals;
38 |
39 | /**
40 | * {@link DiscoveryClientAutoConfiguration} Test
41 | *
42 | * @author Mercy
43 | * @see DiscoveryClientAutoConfiguration
44 | * @since 1.0.0
45 | */
46 | @ExtendWith(SpringExtension.class)
47 | @SpringBootTest(classes = {
48 | UtilAutoConfiguration.class,
49 | SimpleDiscoveryClientAutoConfiguration.class,
50 | CompositeDiscoveryClientAutoConfiguration.class,
51 | DiscoveryClientAutoConfiguration.class,
52 | UnionDiscoveryClientTest.class
53 | })
54 | @TestPropertySource(
55 | properties = {
56 | "microsphere.spring.cloud.client.discovery.mode=union",
57 | "spring.cloud.discovery.client.simple.instances.test[0].instanceId=1",
58 | "spring.cloud.discovery.client.simple.instances.test[0].serviceId=test",
59 | "spring.cloud.discovery.client.simple.instances.test[0].host=127.0.0.1",
60 | "spring.cloud.discovery.client.simple.instances.test[0].port=8080",
61 | "spring.cloud.discovery.client.simple.instances.test[0].metadata.key-1=value-1"
62 | }
63 | )
64 | public class DiscoveryClientAutoConfigurationTest {
65 |
66 | @Autowired
67 | private DiscoveryClient discoveryClient;
68 |
69 | @Test
70 | public void test() {
71 | assertEquals(CompositeDiscoveryClient.class, discoveryClient.getClass());
72 | CompositeDiscoveryClient compositeDiscoveryClient = CompositeDiscoveryClient.class.cast(discoveryClient);
73 | List discoveryClients = compositeDiscoveryClient.getDiscoveryClients();
74 | assertEquals(2, discoveryClients.size());
75 | assertEquals(UnionDiscoveryClient.class, discoveryClients.get(0).getClass());
76 | assertEquals(SimpleDiscoveryClient.class, discoveryClients.get(1).getClass());
77 | List services = compositeDiscoveryClient.getServices();
78 | assertEquals(Arrays.asList("test"), services);
79 | assertEquals(services, discoveryClients.get(0).getServices());
80 | assertEquals(services, discoveryClients.get(1).getServices());
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/discovery/autoconfigure/UnionDiscoveryClientTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.discovery;
18 |
19 | import org.junit.jupiter.api.Test;
20 | import org.junit.jupiter.api.extension.ExtendWith;
21 | import org.springframework.beans.factory.annotation.Autowired;
22 | import org.springframework.cloud.client.discovery.DiscoveryClient;
23 | import org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient;
24 | import org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration;
25 | import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClient;
26 | import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration;
27 | import org.springframework.cloud.commons.util.UtilAutoConfiguration;
28 | import org.springframework.test.context.ContextConfiguration;
29 | import org.springframework.test.context.TestPropertySource;
30 | import org.springframework.test.context.junit.jupiter.SpringExtension;
31 |
32 | import java.util.Arrays;
33 | import java.util.List;
34 |
35 | import static org.junit.jupiter.api.Assertions.assertEquals;
36 |
37 | /**
38 | * {@link UnionDiscoveryClient} Test
39 | *
40 | * @author Mercy
41 | * @since 1.0.0
42 | */
43 | @ExtendWith(SpringExtension.class)
44 | @ContextConfiguration(classes = {
45 | UtilAutoConfiguration.class,
46 | SimpleDiscoveryClientAutoConfiguration.class,
47 | CompositeDiscoveryClientAutoConfiguration.class,
48 | UnionDiscoveryClient.class,
49 | UnionDiscoveryClientTest.class
50 | })
51 | @TestPropertySource(
52 | properties = {
53 | "spring.cloud.discovery.client.simple.instances.test[0].instanceId=1",
54 | "spring.cloud.discovery.client.simple.instances.test[0].serviceId=test",
55 | "spring.cloud.discovery.client.simple.instances.test[0].host=127.0.0.1",
56 | "spring.cloud.discovery.client.simple.instances.test[0].port=8080",
57 | "spring.cloud.discovery.client.simple.instances.test[0].metadata.key-1=value-1"
58 | }
59 | )
60 | public class UnionDiscoveryClientTest {
61 |
62 | @Autowired
63 | private DiscoveryClient discoveryClient;
64 |
65 | @Test
66 | public void test() {
67 | assertEquals(CompositeDiscoveryClient.class, discoveryClient.getClass());
68 | CompositeDiscoveryClient compositeDiscoveryClient = CompositeDiscoveryClient.class.cast(discoveryClient);
69 | List discoveryClients = compositeDiscoveryClient.getDiscoveryClients();
70 | assertEquals(2, discoveryClients.size());
71 | assertEquals(UnionDiscoveryClient.class, discoveryClients.get(0).getClass());
72 | assertEquals(SimpleDiscoveryClient.class, discoveryClients.get(1).getClass());
73 | List services = compositeDiscoveryClient.getServices();
74 | assertEquals(Arrays.asList("test"), services);
75 | assertEquals(services, discoveryClients.get(0).getServices());
76 | assertEquals(services, discoveryClients.get(1).getServices());
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/discovery/constants/DiscoveryClientConstantsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.discovery.constants;
18 |
19 | import org.junit.jupiter.api.Test;
20 |
21 | import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.COMMONS_CLIENT_AUTO_CONFIGURATION_CLASS_NAME;
22 | import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.COMPOSITE_DISCOVERY_CLIENT_CLASS_NAME;
23 | import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.DISCOVERY_CLIENT_CLASS_NAME;
24 | import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.DISCOVERY_CLIENT_PROPERTY_PREFIX;
25 | import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.MODE_PROPERTY_NAME;
26 | import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.UNION_DISCOVERY_CLIENT_MODE;
27 | import static org.junit.jupiter.api.Assertions.assertEquals;
28 |
29 | /**
30 | * {@link DiscoveryClientConstants} Test
31 | *
32 | * @author Mercy
33 | * @see DiscoveryClientConstants
34 | * @since 1.0.0
35 | */
36 | public class DiscoveryClientConstantsTest {
37 |
38 | @Test
39 | public void testConstants() {
40 | assertEquals("microsphere.spring.cloud.client.discovery.", DISCOVERY_CLIENT_PROPERTY_PREFIX);
41 | assertEquals("mode", MODE_PROPERTY_NAME);
42 | assertEquals("union", UNION_DISCOVERY_CLIENT_MODE);
43 |
44 | assertEquals("org.springframework.cloud.client.discovery.DiscoveryClient", DISCOVERY_CLIENT_CLASS_NAME);
45 | assertEquals("org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient", COMPOSITE_DISCOVERY_CLIENT_CLASS_NAME);
46 | assertEquals("org.springframework.cloud.client.CommonsClientAutoConfiguration", COMMONS_CLIENT_AUTO_CONFIGURATION_CLASS_NAME);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/event/ServiceInstancesChangedEventTest.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.client.event;
2 |
3 | import org.junit.jupiter.api.BeforeEach;
4 | import org.junit.jupiter.api.Test;
5 | import org.springframework.cloud.client.DefaultServiceInstance;
6 | import org.springframework.cloud.client.ServiceInstance;
7 |
8 | import java.net.URI;
9 | import java.util.Arrays;
10 | import java.util.UUID;
11 |
12 | import static org.junit.jupiter.api.Assertions.assertEquals;
13 | import static org.junit.jupiter.api.Assertions.assertFalse;
14 | import static org.junit.jupiter.api.Assertions.assertSame;
15 | import static org.junit.jupiter.api.Assertions.assertTrue;
16 |
17 | /**
18 | * {@link ServiceInstancesChangedEvent} Test
19 | *
20 | * @author Mercy
21 | * @see ServiceInstancesChangedEvent
22 | * @since 1.0.0
23 | */
24 | public class ServiceInstancesChangedEventTest {
25 |
26 | private String serviceName = "testService";
27 |
28 | private ServiceInstancesChangedEvent event;
29 |
30 | private ServiceInstance instance;
31 |
32 | @BeforeEach
33 | public void init() {
34 | this.instance = createInstance(serviceName);
35 | this.event = new ServiceInstancesChangedEvent(serviceName, Arrays.asList(instance));
36 | }
37 |
38 | private ServiceInstance createInstance(String serviceName) {
39 | DefaultServiceInstance instance = new DefaultServiceInstance();
40 | instance.setServiceId(serviceName);
41 | instance.setServiceId(UUID.randomUUID().toString());
42 | instance.setHost("127.0.0.1");
43 | instance.setPort(8080);
44 | instance.setUri(URI.create("http://127.0.0.1:8080/info"));
45 | return instance;
46 | }
47 |
48 | @Test
49 | public void testGetServiceName() {
50 | assertEquals(this.serviceName, this.event.getServiceName());
51 | assertEquals(this.serviceName, this.event.getSource());
52 | }
53 |
54 | @Test
55 | public void testGetServiceInstances() {
56 | assertEquals(Arrays.asList(this.instance), this.event.getServiceInstances());
57 | assertEquals(this.instance, this.event.getServiceInstances().get(0));
58 | assertSame(this.instance, this.event.getServiceInstances().get(0));
59 | }
60 |
61 | @Test
62 | public void testProcessed() {
63 | assertFalse(this.event.isProcessed());
64 | this.event.processed();
65 | assertTrue(this.event.isProcessed());
66 | }
67 | }
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/service/registry/MultipleServiceRegistryTest.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.client.service.registry;
2 |
3 | import com.alibaba.cloud.nacos.NacosServiceAutoConfiguration;
4 | import com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration;
5 | import com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration;
6 | import com.netflix.appinfo.ApplicationInfoManager;
7 | import com.netflix.appinfo.InstanceInfo;
8 | import io.microsphere.spring.cloud.client.service.registry.autoconfigure.ServiceRegistryAutoConfiguration;
9 | import io.microsphere.spring.cloud.client.service.registry.event.RegistrationPreRegisteredEvent;
10 | import org.junit.jupiter.api.Disabled;
11 | import org.junit.jupiter.api.Test;
12 | import org.junit.jupiter.api.extension.ExtendWith;
13 | import org.springframework.beans.factory.annotation.Autowired;
14 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
15 | import org.springframework.cloud.client.CommonsClientAutoConfiguration;
16 | import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration;
17 | import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
18 | import org.springframework.cloud.client.serviceregistry.Registration;
19 | import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
20 | import org.springframework.cloud.commons.util.UtilAutoConfiguration;
21 | import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration;
22 | import org.springframework.cloud.netflix.eureka.config.DiscoveryClientOptionalArgsConfiguration;
23 | import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration;
24 | import org.springframework.context.ApplicationListener;
25 | import org.springframework.test.context.ContextConfiguration;
26 | import org.springframework.test.context.TestPropertySource;
27 | import org.springframework.test.context.junit.jupiter.SpringExtension;
28 |
29 | import java.util.Map;
30 |
31 | import static org.junit.jupiter.api.Assertions.assertEquals;
32 | import static org.junit.jupiter.api.Assertions.assertNotNull;
33 |
34 | @Disabled
35 | @ExtendWith(SpringExtension.class)
36 | @ContextConfiguration(classes = {
37 | AutoServiceRegistrationAutoConfiguration.class,
38 | CommonsClientAutoConfiguration.class,
39 | EurekaClientAutoConfiguration.class,
40 | DiscoveryClientOptionalArgsConfiguration.class,
41 | NacosServiceRegistryAutoConfiguration.class,
42 | NacosServiceAutoConfiguration.class,
43 | NacosDiscoveryAutoConfiguration.class,
44 | UtilAutoConfiguration.class,
45 | MultipleServiceRegistryTest.class,
46 | ServiceRegistryAutoConfiguration.class,
47 | })
48 | @TestPropertySource(
49 | properties = {
50 | "spring.application.name=test",
51 | "microsphere.spring.cloud.multiple-registration.enabled=true",
52 | "microsphere.spring.cloud.default-registration.type=com.alibaba.cloud.nacos.registry.NacosRegistration",
53 | "microsphere.spring.cloud.default-service-registry.type=com.alibaba.cloud.nacos.registry.NacosServiceRegistry",
54 | "spring.cloud.service-registry.auto-registration.enabled=true",
55 | "spring.cloud.nacos.discovery.namespace=f7ad23e0-f581-4516-9420-8c50aa6a7b89",
56 | "spring.cloud.nacos.discovery.metadata.key=value",
57 | "eureka.client.service-url.defaultZone=http://127.0.0.1:8080/eureka",
58 | }
59 | )
60 | @EnableAutoConfiguration
61 | class MultipleServiceRegistryTest implements ApplicationListener {
62 |
63 | @Autowired
64 | private ServiceRegistry serviceRegistry;
65 |
66 | @Autowired
67 | private AutoServiceRegistrationProperties properties;
68 |
69 | @Autowired
70 | private Registration registration;
71 |
72 | @Autowired
73 | private MultipleAutoServiceRegistration autoServiceRegistration;
74 |
75 | @Override
76 | public void onApplicationEvent(RegistrationPreRegisteredEvent event) {
77 | this.registration.getMetadata().put("my-key", "my-value");
78 | if (event.getRegistration() instanceof EurekaRegistration) {
79 | EurekaRegistration eurekaRegistration = (EurekaRegistration) event.getRegistration();
80 |
81 |
82 | ApplicationInfoManager applicationInfoManager = eurekaRegistration.getApplicationInfoManager();
83 | InstanceInfo instanceInfo = applicationInfoManager.getInfo();
84 | Map metadata = registration.getMetadata();
85 | // Sync metadata from Registration to InstanceInfo
86 | instanceInfo.getMetadata().putAll(metadata);
87 | }
88 | }
89 |
90 | @Test
91 | public void test() throws Exception {
92 | assertNotNull(serviceRegistry);
93 | assertNotNull(registration);
94 | autoServiceRegistration.start();
95 | Thread.sleep(60 * 1000);
96 |
97 | autoServiceRegistration.stop();
98 | }
99 |
100 | @Test
101 | public void testMetaData() throws Exception {
102 | assertNotNull(registration);
103 |
104 | autoServiceRegistration.start();
105 |
106 | assertEquals(registration.getMetadata().get("my-key"), "my-value");
107 | Thread.sleep(60 * 1000);
108 |
109 | autoServiceRegistration.stop();
110 | }
111 |
112 |
113 | }
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/service/registry/actuate/autoconfigure/ServiceRegistrationEndpointAutoConfigurationTest.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.client.service.registry.actuate.autoconfigure;
2 |
3 | import io.microsphere.spring.cloud.client.service.registry.endpoint.ServiceDeregistrationEndpoint;
4 | import io.microsphere.spring.cloud.client.service.registry.endpoint.ServiceRegistrationEndpoint;
5 | import org.junit.jupiter.api.Test;
6 | import org.springframework.beans.factory.ObjectProvider;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
9 | import org.springframework.boot.test.context.SpringBootTest;
10 |
11 | import static org.junit.jupiter.api.Assertions.assertNotNull;
12 |
13 | /**
14 | * {@link ServiceRegistrationEndpointAutoConfiguration} Test
15 | *
16 | * @author Mercy
17 | * @see ServiceRegistrationEndpointAutoConfiguration
18 | * @since 1.0.0
19 | */
20 | @SpringBootTest(
21 | classes = {
22 | ServiceRegistrationEndpointAutoConfigurationTest.class
23 | },
24 | webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
25 | properties = {
26 | "microsphere.spring.cloud.service-registry.auto-registration.simple.enabled=true",
27 | "management.endpoint.serviceRegistration.enabled=true",
28 | "management.endpoint.serviceDeregistration.enabled=true",
29 | }
30 | )
31 | @EnableAutoConfiguration
32 | public class ServiceRegistrationEndpointAutoConfigurationTest {
33 |
34 | @Autowired
35 | private ObjectProvider serviceRegistrationEndpoint;
36 |
37 | @Autowired
38 | private ObjectProvider serviceDeregistrationEndpoint;
39 |
40 | @Test
41 | public void testEndpoints() {
42 | assertNotNull(serviceRegistrationEndpoint);
43 | }
44 |
45 | }
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/SimpleAutoServiceRegistrationAutoConfigurationTest.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.client.service.registry.autoconfigure;
2 |
3 | import io.microsphere.spring.cloud.client.service.registry.SimpleAutoServiceRegistration;
4 | import org.junit.jupiter.api.Test;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 | import org.springframework.cloud.client.serviceregistry.Registration;
9 | import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
10 |
11 | import static org.junit.jupiter.api.Assertions.assertEquals;
12 | import static org.junit.jupiter.api.Assertions.assertNotNull;
13 |
14 | /**
15 | * {@link SimpleAutoServiceRegistrationAutoConfiguration} Test
16 | *
17 | * @author Mercy
18 | * @see SimpleAutoServiceRegistrationAutoConfiguration
19 | * @since 1.0.0
20 | */
21 | @SpringBootTest(
22 | classes = {
23 | SimpleAutoServiceRegistrationAutoConfigurationTest.class
24 | },
25 | webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
26 | properties = {
27 | "microsphere.spring.cloud.service-registry.auto-registration.simple.enabled=true",
28 | "spring.application.name=test-service"
29 | }
30 | )
31 | @EnableAutoConfiguration
32 | public class SimpleAutoServiceRegistrationAutoConfigurationTest {
33 |
34 | @Autowired
35 | private Registration registration;
36 |
37 | @Autowired
38 | private ServiceRegistry serviceRegistry;
39 |
40 | @Autowired
41 | private SimpleAutoServiceRegistration simpleAutoServiceRegistration;
42 |
43 | @Test
44 | public void test() {
45 | assertEquals("test-service", registration.getServiceId());
46 | assertNotNull(registration.getHost());
47 | assertNotNull(registration.getPort());
48 | assertNotNull(registration.getUri());
49 | assertNotNull(registration.getInstanceId());
50 | assertNotNull(registration.getMetadata());
51 | }
52 |
53 | }
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/WebMvcServiceRegistryAutoConfigurationTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.client.service.registry.autoconfigure;
18 |
19 | import io.microsphere.spring.webmvc.annotation.EnableWebMvcExtension;
20 | import org.junit.jupiter.api.Test;
21 | import org.springframework.beans.factory.annotation.Autowired;
22 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
23 | import org.springframework.boot.test.context.SpringBootTest;
24 | import org.springframework.cloud.client.serviceregistry.Registration;
25 |
26 | import java.util.Map;
27 |
28 | import static io.microsphere.spring.cloud.client.service.registry.constants.InstanceConstants.WEB_MAPPINGS_METADATA_NAME;
29 | import static org.junit.jupiter.api.Assertions.assertNotNull;
30 |
31 | /**
32 | * {@link WebMvcServiceRegistryAutoConfiguration} Test
33 | *
34 | * @author Mercy
35 | * @since 1.0.0
36 | */
37 | @SpringBootTest(
38 | classes = {WebMvcServiceRegistryAutoConfigurationTest.class},
39 | properties = {
40 | "microsphere.spring.cloud.service-registry.auto-registration.simple.enabled=true",
41 | "spring.cloud.service-registry.auto-registration.enabled=true",
42 | "spring.cloud.kubernetes.enabled=false",
43 | "kubernetes.informer.enabled=false",
44 | "kubernetes.manifests.enabled=false",
45 | "kubernetes.reconciler.enabled=false"
46 | },
47 | webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
48 | )
49 | @EnableAutoConfiguration
50 | @EnableWebMvcExtension
51 | public class WebMvcServiceRegistryAutoConfigurationTest {
52 |
53 | @Autowired
54 | private Registration registration;
55 |
56 | @Test
57 | public void test() {
58 | Map metadata = registration.getMetadata();
59 | assertNotNull(metadata.get(WEB_MAPPINGS_METADATA_NAME));
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/commons/constants/CommonsPropertyConstantsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package io.microsphere.spring.cloud.commons.constants;
18 |
19 | import org.junit.jupiter.api.Test;
20 |
21 | import static io.microsphere.spring.cloud.commons.constants.CommonsPropertyConstants.COMPOSITE_REGISTRATION_ENABLED_PROPERTY_NAME;
22 | import static io.microsphere.spring.cloud.commons.constants.CommonsPropertyConstants.FEATURES_ENABLED_PROPERTY_NAME;
23 | import static io.microsphere.spring.cloud.commons.constants.CommonsPropertyConstants.MICROSPHERE_SPRING_CLOUD_PROPERTY_NAME_PREFIX;
24 | import static io.microsphere.spring.cloud.commons.constants.CommonsPropertyConstants.MICROSPHERE_SPRING_CLOUD_WEB_MVC_PROPERTY_NAME_PREFIX;
25 | import static io.microsphere.spring.cloud.commons.constants.CommonsPropertyConstants.MULTIPLE_REGISTRATION_DEFAULT_REGISTRATION_PROPERTY_NAME;
26 | import static io.microsphere.spring.cloud.commons.constants.CommonsPropertyConstants.MULTIPLE_REGISTRATION_DEFAULT_REGISTRY_PROPERTY_NAME;
27 | import static io.microsphere.spring.cloud.commons.constants.CommonsPropertyConstants.MULTIPLE_REGISTRATION_ENABLED_PROPERTY_NAME;
28 | import static io.microsphere.spring.cloud.commons.constants.CommonsPropertyConstants.SERVICE_REGISTRY_AUTO_REGISTRATION_ENABLED_PROPERTY_NAME;
29 | import static io.microsphere.spring.cloud.commons.constants.CommonsPropertyConstants.SERVICE_REGISTRY_PROPERTY_PREFIX;
30 | import static io.microsphere.spring.cloud.commons.constants.CommonsPropertyConstants.SPRING_CLOUD_PROPERTY_PREFIX;
31 | import static org.junit.jupiter.api.Assertions.assertEquals;
32 |
33 | /**
34 | * {@link CommonsPropertyConstants} Test
35 | *
36 | * @author Mercy
37 | * @see CommonsPropertyConstants
38 | * @since 1.0.0
39 | */
40 | public class CommonsPropertyConstantsTest {
41 |
42 | @Test
43 | public void testConstants() {
44 | assertEquals("spring.cloud.", SPRING_CLOUD_PROPERTY_PREFIX);
45 | assertEquals("spring.cloud.service-registry.", SERVICE_REGISTRY_PROPERTY_PREFIX);
46 | assertEquals("spring.cloud.service-registry.auto-registration.enabled", SERVICE_REGISTRY_AUTO_REGISTRATION_ENABLED_PROPERTY_NAME);
47 | assertEquals("spring.cloud.features.enabled", FEATURES_ENABLED_PROPERTY_NAME);
48 | assertEquals("microsphere.spring.cloud.", MICROSPHERE_SPRING_CLOUD_PROPERTY_NAME_PREFIX);
49 | assertEquals("microsphere.spring.cloud.web.mvc.", MICROSPHERE_SPRING_CLOUD_WEB_MVC_PROPERTY_NAME_PREFIX);
50 | assertEquals("microsphere.spring.cloud.multiple-registration.enabled", MULTIPLE_REGISTRATION_ENABLED_PROPERTY_NAME);
51 | assertEquals("microsphere.spring.cloud.default-registration.type", MULTIPLE_REGISTRATION_DEFAULT_REGISTRATION_PROPERTY_NAME);
52 | assertEquals("microsphere.spring.cloud.default-service-registry.type", MULTIPLE_REGISTRATION_DEFAULT_REGISTRY_PROPERTY_NAME);
53 | assertEquals("microsphere.spring.cloud.composite-registration.enabled", COMPOSITE_REGISTRATION_ENABLED_PROPERTY_NAME);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-commons/src/test/resources/application.yaml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: microsphere-spring-cloud-commons-application
4 |
5 | # default disable all
6 | cloud:
7 | nacos:
8 | discovery:
9 | enabled: false
10 | register-enabled: false
11 | config:
12 | import-check.enabled: false
13 | zookeeper:
14 | enabled: false
15 | consul:
16 | enabled: false
17 | kubernetes:
18 | enabled: false
19 | config:
20 | enabled: false
21 | enableApi: false
22 | secrets:
23 | enabled: false
24 |
25 | eureka:
26 | client:
27 | enabled: false
28 |
29 |
30 | ---
31 | spring:
32 | config:
33 | activate:
34 | on-profile: nacos
35 |
36 | cloud:
37 | nacos:
38 | username: nacos
39 | password: nacos
40 | discovery:
41 | enabled: true
42 | register-enabled: true
43 | server-addr: 127.0.0.1:8848
44 | ephemeral: false
45 |
46 |
47 | ---
48 | spring:
49 | config:
50 | activate:
51 | on-profile: eureka
52 |
53 | eureka:
54 | client:
55 | enabled: true
56 | service-url:
57 | defaultZone: http://127.0.0.1:8761/eureka/
58 |
59 |
60 | ---
61 | spring:
62 | config:
63 | activate:
64 | on-profile: zookeeper
65 | cloud:
66 | zookeeper:
67 | enabled: true
68 | connect-string: 127.0.0.1:2181
69 |
70 |
71 | ---
72 | spring:
73 | config:
74 | activate:
75 | on-profile: consul
76 |
77 | cloud:
78 | consul:
79 | enabled: true
80 | host: 127.0.0.1
81 | port: 8500
82 |
83 |
84 | ---
85 | spring:
86 | config:
87 | activate:
88 | on-profile: kubernetes
89 |
90 | cloud:
91 | kubernetes:
92 | enabled: true
--------------------------------------------------------------------------------
/microsphere-spring-cloud-dependencies/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | io.github.microsphere-projects
7 | microsphere-spring-cloud-parent
8 | ${revision}
9 | ../microsphere-spring-cloud-parent/pom.xml
10 |
11 | 4.0.0
12 |
13 | io.github.microsphere-projects
14 | microsphere-spring-cloud-dependencies
15 | ${revision}
16 | pom
17 |
18 | Microsphere :: Spring Cloud :: Dependencies
19 | Microsphere Spring Cloud Dependencies
20 |
21 |
22 |
23 |
24 |
25 | io.github.microsphere-projects
26 | microsphere-spring-cloud-commons
27 | ${revision}
28 |
29 |
30 |
31 | io.github.microsphere-projects
32 | microsphere-spring-cloud-openfeign
33 | ${revision}
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | io.github.microsphere-projects
8 | microsphere-spring-cloud-parent
9 | ${revision}
10 | ../microsphere-spring-cloud-parent/pom.xml
11 |
12 |
13 | microsphere-spring-cloud-openfeign
14 | ${revision}
15 |
16 | io.github.microsphere-projects
17 |
18 | Microsphere :: Spring Cloud :: OpenFeign
19 | Microsphere Spring Cloud OpenFeign
20 |
21 |
22 | 8
23 | 8
24 | UTF-8
25 |
26 |
27 |
28 |
29 |
30 |
31 | io.github.microsphere-projects
32 | microsphere-spring-boot-core
33 |
34 |
35 |
36 | org.springframework.cloud
37 | spring-cloud-starter-openfeign
38 | true
39 |
40 |
41 | org.springframework.cloud
42 | spring-cloud-netflix-ribbon
43 |
44 |
45 |
46 |
47 |
48 | org.springframework.cloud
49 | spring-cloud-starter-loadbalancer
50 | true
51 |
52 |
53 |
54 | org.springframework.boot
55 | spring-boot-starter-test
56 | test
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autoconfigure/EnableFeignAutoRefresh.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.autoconfigure;
2 |
3 | import org.springframework.context.annotation.Import;
4 |
5 | import java.lang.annotation.Documented;
6 | import java.lang.annotation.ElementType;
7 | import java.lang.annotation.Inherited;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 |
12 | /**
13 | * Enable Feign Auto Refresh
14 | *
15 | * @author 韩超
16 | * @author Mercy
17 | * @see FeignClientAutoRefreshAutoConfiguration
18 | * @since 0.0.1
19 | */
20 | @Retention(RetentionPolicy.RUNTIME)
21 | @Target({ElementType.TYPE})
22 | @Documented
23 | @Inherited
24 | @Import(EnableFeignAutoRefresh.Marker.class)
25 | public @interface EnableFeignAutoRefresh {
26 |
27 | class Marker {
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autoconfigure/FeignClientAutoRefreshAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.autoconfigure;
2 |
3 | import io.microsphere.spring.cloud.openfeign.autorefresh.FeignClientConfigurationChangedListener;
4 | import io.microsphere.spring.cloud.openfeign.autorefresh.FeignComponentRegistry;
5 | import io.microsphere.spring.cloud.openfeign.components.NoOpRequestInterceptor;
6 | import org.springframework.beans.factory.BeanFactory;
7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
8 | import org.springframework.boot.context.event.ApplicationReadyEvent;
9 | import org.springframework.cloud.openfeign.FeignBuilderCustomizer;
10 | import org.springframework.cloud.openfeign.FeignClientProperties;
11 | import org.springframework.context.ConfigurableApplicationContext;
12 | import org.springframework.context.annotation.Bean;
13 | import org.springframework.context.event.EventListener;
14 |
15 | /**
16 | * The Auto-Configuration class for {@link EnableFeignAutoRefresh}
17 | *
18 | * @author 韩超
19 | * @author Mercy
20 | * @see EnableFeignAutoRefresh
21 | * @since 0.0.1
22 | */
23 | @ConditionalOnBean(EnableFeignAutoRefresh.Marker.class)
24 | public class FeignClientAutoRefreshAutoConfiguration {
25 |
26 | @Bean
27 | public FeignBuilderCustomizer addDefaultRequestInterceptorCustomizer() {
28 | return builder -> {
29 | builder.requestInterceptor(NoOpRequestInterceptor.INSTANCE);
30 | };
31 | }
32 |
33 | @EventListener(ApplicationReadyEvent.class)
34 | public void onApplicationReadyEvent(ApplicationReadyEvent event) {
35 | /**
36 | * Make sure the FeignClientConfigurationChangedListener is registered after the ConfigurationPropertiesRebinder
37 | */
38 | registerFeignClientConfigurationChangedListener(event);
39 | }
40 |
41 | @Bean
42 | public FeignComponentRegistry feignClientRegistry(FeignClientProperties clientProperties, BeanFactory beanFactory) {
43 | return new FeignComponentRegistry(clientProperties.getDefaultConfig(), beanFactory);
44 | }
45 |
46 | @Bean
47 | public FeignClientSpecificationPostProcessor feignClientSpecificationPostProcessor() {
48 | return new FeignClientSpecificationPostProcessor();
49 | }
50 |
51 | private void registerFeignClientConfigurationChangedListener(ApplicationReadyEvent event) {
52 | ConfigurableApplicationContext context = event.getApplicationContext();
53 | FeignComponentRegistry feignComponentRegistry = context.getBean(FeignComponentRegistry.class);
54 | context.addApplicationListener(new FeignClientConfigurationChangedListener(feignComponentRegistry));
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autoconfigure/FeignClientSpecificationPostProcessor.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.autoconfigure;
2 |
3 | import io.microsphere.logging.Logger;
4 | import io.microsphere.spring.cloud.openfeign.autorefresh.AutoRefreshCapability;
5 | import org.springframework.beans.BeansException;
6 | import org.springframework.beans.factory.config.BeanPostProcessor;
7 | import org.springframework.cloud.context.named.NamedContextFactory;
8 |
9 | import java.lang.reflect.Method;
10 | import java.util.Arrays;
11 |
12 | import static io.microsphere.logging.LoggerFactory.getLogger;
13 | import static io.microsphere.reflect.MethodUtils.findMethod;
14 | import static io.microsphere.util.ArrayUtils.combine;
15 | import static org.springframework.aop.support.AopUtils.getTargetClass;
16 | import static org.springframework.util.ClassUtils.resolveClassName;
17 |
18 | /**
19 | * @author 韩超
20 | * @author Mercy
21 | * @see org.springframework.cloud.openfeign.FeignClientSpecification
22 | * @since 0.0.1
23 | */
24 | public class FeignClientSpecificationPostProcessor implements BeanPostProcessor {
25 |
26 | private static final Logger logger = getLogger(FeignClientSpecificationPostProcessor.class);
27 |
28 | private static final Class> AUTO_REFRESH_CAPABILITY_CLASS = AutoRefreshCapability.class;
29 |
30 | private static final String FEIGN_CLIENT_SPECIFICATION_CLASS_NAME = "org.springframework.cloud.openfeign.FeignClientSpecification";
31 |
32 | private static final Class> FEIGN_CLIENT_SPECIFICATION_CLASS = resolveClassName(FEIGN_CLIENT_SPECIFICATION_CLASS_NAME, null);
33 |
34 | private static final Method setConfigurationMethod = findMethod(FEIGN_CLIENT_SPECIFICATION_CLASS, "setConfiguration", Class[].class);
35 |
36 | @Override
37 | public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
38 | Class> beanType = getTargetClass(bean);
39 | if (FEIGN_CLIENT_SPECIFICATION_CLASS.isAssignableFrom(beanType) && beanName.startsWith("default")) {
40 | injectAutoRefreshCapability((NamedContextFactory.Specification) bean);
41 | }
42 | return bean;
43 | }
44 |
45 | private void injectAutoRefreshCapability(NamedContextFactory.Specification defaultSpecification) {
46 | if (setConfigurationMethod != null) {
47 | Class>[] originConfigurationClasses = defaultSpecification.getConfiguration();
48 | Class>[] newConfigurationClasses = combine(AUTO_REFRESH_CAPABILITY_CLASS, originConfigurationClasses);
49 | Object arg = newConfigurationClasses;
50 | try {
51 | setConfigurationMethod.setAccessible(true);
52 | setConfigurationMethod.invoke(defaultSpecification, arg);
53 | } catch (Throwable e) {
54 | if (logger.isWarnEnabled()) {
55 | logger.warn("FeignClientSpecification#setConfiguration(Class[]) can't be invoked , instance : {} , args : {}",
56 | defaultSpecification, Arrays.toString(newConfigurationClasses));
57 | }
58 | }
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autorefresh/FeignClientConfigurationChangedListener.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.autorefresh;
2 |
3 | import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
4 | import org.springframework.context.ApplicationListener;
5 |
6 | import java.util.Map;
7 | import java.util.Set;
8 | import java.util.stream.Collectors;
9 |
10 | /**
11 | * @author 韩超
12 | * @since 0.0.1
13 | */
14 | public class FeignClientConfigurationChangedListener implements ApplicationListener {
15 |
16 | private final FeignComponentRegistry registry;
17 |
18 | public FeignClientConfigurationChangedListener(FeignComponentRegistry registry) {
19 | this.registry = registry;
20 | }
21 |
22 | private final String PREFIX = "spring.cloud.openfeign.client.config.";
23 |
24 | @Override
25 | public void onApplicationEvent(EnvironmentChangeEvent event) {
26 | Map> effectiveClients = resolveChangedClient(event);
27 | if (!effectiveClients.isEmpty()) {
28 | effectiveClients.forEach(registry::refresh);
29 | }
30 | }
31 |
32 | protected Map> resolveChangedClient(EnvironmentChangeEvent event) {
33 | Set keys = event.getKeys();
34 | return keys.stream()
35 | .filter(str -> str.startsWith(PREFIX))
36 | .map(str -> str.replace(PREFIX, ""))
37 | .collect(Collectors.groupingBy(str -> {
38 | int index = str.indexOf(".");
39 | return str.substring(0, index);
40 | }, Collectors.toSet()));
41 |
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/components/CompositedRequestInterceptor.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.components;
2 |
3 | import feign.RequestInterceptor;
4 | import feign.RequestTemplate;
5 | import org.springframework.beans.BeanUtils;
6 | import org.springframework.beans.factory.BeanFactory;
7 | import org.springframework.cloud.openfeign.FeignClientProperties;
8 | import org.springframework.util.CollectionUtils;
9 |
10 | import java.util.Collection;
11 | import java.util.Collections;
12 | import java.util.HashMap;
13 | import java.util.HashSet;
14 | import java.util.Map;
15 | import java.util.Set;
16 |
17 | /**
18 | * @author 韩超
19 | * @since 0.0.1
20 | */
21 | public class CompositedRequestInterceptor implements RequestInterceptor, Refreshable {
22 |
23 | private final BeanFactory beanFactory;
24 | private final String contextId;
25 |
26 | private final Set set = new HashSet<>();
27 |
28 | public CompositedRequestInterceptor(String contextId, BeanFactory beanFactory) {
29 | this.beanFactory = beanFactory;
30 | this.contextId = contextId;
31 | }
32 |
33 | public Set getRequestInterceptors() {
34 | return Collections.unmodifiableSet(set);
35 | }
36 |
37 |
38 | @Override
39 | public void apply(RequestTemplate template) {
40 | synchronized (this.set) {
41 | if (!this.set.isEmpty())
42 | set.forEach(requestInterceptor -> requestInterceptor.apply(template));
43 | }
44 |
45 | }
46 |
47 | public boolean addRequestInterceptor(RequestInterceptor requestInterceptor) {
48 | synchronized (this.set) {
49 | boolean isFirst = this.set.isEmpty();
50 | this.set.add(requestInterceptor);
51 | return isFirst;
52 | }
53 |
54 | }
55 |
56 | private RequestInterceptor getInterceptorOrInstantiate(Class extends RequestInterceptor> clazz) {
57 | try {
58 | return this.beanFactory.getBean(clazz);
59 | } catch (Exception e) {
60 | return BeanUtils.instantiateClass(clazz);
61 | }
62 | }
63 |
64 | @Override
65 | public void refresh() {
66 | FeignClientProperties properties = this.beanFactory.getBean(FeignClientProperties.class);
67 | Set> interceptors = new HashSet<>();
68 | //headers
69 | Map> headers = new HashMap<>();
70 | Map> params = new HashMap<>();
71 | if (properties != null) {
72 | FeignClientProperties.FeignClientConfiguration defaultConfiguration = properties.getConfig().get(properties.getDefaultConfig());
73 | FeignClientProperties.FeignClientConfiguration current = properties.getConfig().get(contextId);
74 | if (defaultConfiguration != null && defaultConfiguration.getRequestInterceptors() != null)
75 | interceptors.addAll(defaultConfiguration.getRequestInterceptors());
76 | if (current != null && current.getRequestInterceptors() != null)
77 | interceptors.addAll(current.getRequestInterceptors());
78 |
79 | if (defaultConfiguration != null && defaultConfiguration.getDefaultRequestHeaders() != null)
80 | headers.putAll(defaultConfiguration.getDefaultRequestHeaders());
81 |
82 | if (current != null && current.getDefaultRequestHeaders() != null) {
83 | current.getDefaultRequestHeaders().forEach(headers::putIfAbsent);
84 | }
85 |
86 | if (defaultConfiguration != null && defaultConfiguration.getDefaultQueryParameters() != null)
87 | params.putAll(defaultConfiguration.getDefaultRequestHeaders());
88 |
89 | if (current != null && current.getDefaultQueryParameters() != null) {
90 | current.getDefaultQueryParameters().forEach(params::putIfAbsent);
91 | }
92 |
93 | }
94 |
95 | synchronized (this.set) {
96 | this.set.clear();
97 | for (Class interceptorClass : interceptors)
98 | set.add(getInterceptorOrInstantiate(interceptorClass));
99 |
100 | if (!CollectionUtils.isEmpty(headers))
101 | set.add(requestTemplate -> {
102 | Map> requestHeader = requestTemplate.headers();
103 | headers.keySet().forEach(key -> {
104 | if (!requestHeader.containsKey(key)) {
105 | requestTemplate.header(key, headers.get(key));
106 | }
107 | });
108 | });
109 |
110 | if (!CollectionUtils.isEmpty(params))
111 | set.add(requestTemplate -> {
112 | Map> requestQueries = requestTemplate.queries();
113 | params.keySet().forEach(key -> {
114 | if (!requestQueries.containsKey(key)) {
115 | requestTemplate.query(key, params.get(key));
116 | }
117 | });
118 | });
119 | }
120 |
121 |
122 |
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/components/DecoratedContract.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.components;
2 |
3 | import feign.Contract;
4 | import feign.MethodMetadata;
5 | import org.springframework.cloud.context.named.NamedContextFactory;
6 | import org.springframework.cloud.openfeign.FeignClientProperties;
7 | import org.springframework.cloud.openfeign.FeignClientSpecification;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * @author 韩超
13 | * @since 0.0.1
14 | */
15 | public class DecoratedContract extends DecoratedFeignComponent implements Contract {
16 |
17 | public DecoratedContract(String contextId, NamedContextFactory contextFactory, FeignClientProperties clientProperties, Contract delegate) {
18 | super(contextId, contextFactory, clientProperties, delegate);
19 | }
20 |
21 | @Override
22 | protected Class componentType() {
23 | Class contractClass = null;
24 | if (getDefaultConfiguration() != null && getDefaultConfiguration().getContract() != null)
25 | contractClass = getDefaultConfiguration().getContract();
26 |
27 | if (getCurrentConfiguration() != null && getCurrentConfiguration().getContract() != null)
28 | contractClass = getCurrentConfiguration().getContract();
29 |
30 | if (contractClass != null)
31 | return contractClass;
32 | return Contract.class;
33 | }
34 |
35 | @Override
36 | public List parseAndValidateMetadata(Class> targetType) {
37 | return delegate().parseAndValidateMetadata(targetType);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/components/DecoratedDecoder.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.components;
2 |
3 | import feign.FeignException;
4 | import feign.Response;
5 | import feign.codec.DecodeException;
6 | import feign.codec.Decoder;
7 | import org.springframework.cloud.context.named.NamedContextFactory;
8 | import org.springframework.cloud.openfeign.FeignClientProperties;
9 | import org.springframework.cloud.openfeign.FeignClientSpecification;
10 |
11 | import java.io.IOException;
12 | import java.lang.reflect.Type;
13 |
14 | /**
15 | * @author 韩超
16 | * @since 0.0.1
17 | */
18 | public class DecoratedDecoder extends DecoratedFeignComponent implements Decoder {
19 |
20 | public DecoratedDecoder(String contextId, NamedContextFactory contextFactory, FeignClientProperties clientProperties, Decoder delegate) {
21 | super(contextId, contextFactory, clientProperties, delegate);
22 | }
23 |
24 | @Override
25 | protected Class componentType() {
26 | Class decoderClass = null;
27 | if (getDefaultConfiguration() != null && getDefaultConfiguration().getDecoder() != null)
28 | decoderClass = getDefaultConfiguration().getDecoder();
29 |
30 | if (getCurrentConfiguration() != null && getCurrentConfiguration().getDecoder() != null)
31 | decoderClass = getCurrentConfiguration().getDecoder();
32 |
33 | if (decoderClass != null)
34 | return decoderClass;
35 | return Decoder.class;
36 | }
37 |
38 | @Override
39 | public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {
40 | return delegate().decode(response, type);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/components/DecoratedEncoder.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.components;
2 |
3 | import feign.RequestTemplate;
4 | import feign.codec.EncodeException;
5 | import feign.codec.Encoder;
6 | import org.springframework.cloud.context.named.NamedContextFactory;
7 | import org.springframework.cloud.openfeign.FeignClientProperties;
8 | import org.springframework.cloud.openfeign.FeignClientSpecification;
9 |
10 | import java.lang.reflect.Type;
11 |
12 | /**
13 | * @author 韩超
14 | * @since 0.0.1
15 | */
16 | public class DecoratedEncoder extends DecoratedFeignComponent implements Encoder {
17 |
18 | public DecoratedEncoder(String contextId, NamedContextFactory contextFactory, FeignClientProperties clientProperties, Encoder delegate) {
19 | super(contextId, contextFactory, clientProperties, delegate);
20 | }
21 |
22 | @Override
23 | protected Class componentType() {
24 | Class encoderClass = null;
25 | if (getDefaultConfiguration() != null && getDefaultConfiguration().getEncoder() != null)
26 | encoderClass = getDefaultConfiguration().getEncoder();
27 |
28 | if (getCurrentConfiguration() != null && getCurrentConfiguration().getEncoder() != null)
29 | encoderClass = getCurrentConfiguration().getEncoder();
30 |
31 | if (encoderClass != null)
32 | return encoderClass;
33 | return Encoder.class;
34 | }
35 |
36 | @Override
37 | public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {
38 | delegate().encode(object, bodyType, template);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/components/DecoratedErrorDecoder.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.components;
2 |
3 | import feign.Response;
4 | import feign.codec.ErrorDecoder;
5 | import org.springframework.cloud.context.named.NamedContextFactory;
6 | import org.springframework.cloud.openfeign.FeignClientProperties;
7 | import org.springframework.cloud.openfeign.FeignClientSpecification;
8 |
9 | /**
10 | * @author 韩超
11 | * @since 0.0.1
12 | */
13 | public class DecoratedErrorDecoder extends DecoratedFeignComponent implements ErrorDecoder {
14 |
15 | public DecoratedErrorDecoder(String contextId, NamedContextFactory contextFactory, FeignClientProperties clientProperties, ErrorDecoder delegate) {
16 | super(contextId, contextFactory, clientProperties, delegate);
17 | }
18 |
19 | @Override
20 | protected Class componentType() {
21 | Class errorDecoderClass = null;
22 | if (getDefaultConfiguration() != null && getDefaultConfiguration().getErrorDecoder() != null)
23 | errorDecoderClass = getDefaultConfiguration().getErrorDecoder();
24 |
25 | if (getCurrentConfiguration() != null && getCurrentConfiguration().getErrorDecoder() != null)
26 | errorDecoderClass = getCurrentConfiguration().getErrorDecoder();
27 |
28 | if (errorDecoderClass != null)
29 | return errorDecoderClass;
30 | return ErrorDecoder.class;
31 | }
32 |
33 | @Override
34 | public Exception decode(String methodKey, Response response) {
35 | return delegate().decode(methodKey, response);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/components/DecoratedFeignComponent.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.components;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.beans.BeanInstantiationException;
6 | import org.springframework.beans.BeanUtils;
7 | import org.springframework.cloud.context.named.NamedContextFactory;
8 | import org.springframework.cloud.openfeign.FeignClientProperties;
9 | import org.springframework.cloud.openfeign.FeignClientSpecification;
10 | import org.springframework.lang.NonNull;
11 |
12 | import java.lang.reflect.Constructor;
13 | import java.util.concurrent.locks.ReentrantReadWriteLock;
14 |
15 | /**
16 | * @author 韩超
17 | * @since 0.0.1
18 | */
19 | public abstract class DecoratedFeignComponent implements Refreshable {
20 |
21 | private final Logger log = LoggerFactory.getLogger(getClass());
22 |
23 | //private final FeignClientFactory feignClientFactory;
24 | private final NamedContextFactory contextFactory;
25 | private final String contextId;
26 |
27 | private final FeignClientProperties clientProperties;
28 |
29 |
30 | protected volatile T delegate;
31 |
32 | private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
33 |
34 | private final ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
35 | private final ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
36 |
37 | public DecoratedFeignComponent(String contextId, NamedContextFactory contextFactory, FeignClientProperties clientProperties, T delegate) {
38 | this.contextId = contextId;
39 | this.contextFactory = contextFactory;
40 | this.clientProperties = clientProperties;
41 | this.delegate = delegate;
42 | }
43 |
44 | public T delegate() {
45 | readLock.lock();
46 | if (delegate == null) {
47 | log.trace("the component {} - Creating delegate instance for contextId: {}", componentType().getSimpleName(), contextId);
48 | readLock.unlock();
49 | return loadInstance();
50 | }
51 |
52 | readLock.unlock();
53 | return this.delegate;
54 | }
55 |
56 | @NonNull
57 | public T loadInstanceFromContextFactory(String contextId, Class componentType) {
58 | T component = this.contextFactory.getInstance(contextId, componentType);
59 | if (component == null)
60 | return this.contextFactory.getParent().getAutowireCapableBeanFactory().createBean(componentType);
61 | return component;
62 | }
63 |
64 | @NonNull
65 | public String contextId() {
66 | return this.contextId;
67 | }
68 |
69 | public void refresh() {
70 | writeLock.lock();
71 | log.debug("the component {} - Refreshing delegate instance for contextId: {}", componentType().getSimpleName(), contextId);
72 | this.delegate = null;
73 | writeLock.unlock();
74 | }
75 |
76 | protected abstract Class componentType();
77 |
78 | public FeignClientProperties.FeignClientConfiguration getDefaultConfiguration() {
79 | return this.clientProperties.getConfig().get(this.clientProperties.getDefaultConfig());
80 | }
81 |
82 | public FeignClientProperties.FeignClientConfiguration getCurrentConfiguration() {
83 | return this.clientProperties.getConfig().get(contextId);
84 | }
85 |
86 | protected T loadInstance() {
87 | Class componentType = componentType();
88 | String contextId = contextId();
89 | writeLock.lock();
90 | try {
91 | T component = loadInstanceFromContextFactory(contextId, componentType);
92 | this.delegate = component;
93 | return component;
94 | } catch (Throwable ex) {
95 | this.delegate = BeanUtils.instantiateClass(componentType);
96 | return delegate;
97 | } finally {
98 | writeLock.unlock();
99 | }
100 | }
101 |
102 | @Override
103 | public int hashCode() {
104 | return delegate().hashCode();
105 | }
106 |
107 | @Override
108 | public boolean equals(Object obj) {
109 | return delegate().equals(obj);
110 | }
111 |
112 | @Override
113 | public String toString() {
114 | return delegate().toString();
115 | }
116 |
117 | public static , T> W instantiate(Class decoratedClass, Class componentClass,
118 | String contextId, NamedContextFactory contextFactory, FeignClientProperties clientProperties, T delegate) {
119 | try {
120 | Constructor constructor = decoratedClass.getConstructor(String.class, NamedContextFactory.class, FeignClientProperties.class, componentClass);
121 | return BeanUtils.instantiateClass(constructor, contextId, contextFactory, clientProperties, delegate);
122 | } catch (NoSuchMethodException noSuchMethodException) {
123 | throw new BeanInstantiationException(decoratedClass, noSuchMethodException.getLocalizedMessage());
124 | }
125 |
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/components/DecoratedQueryMapEncoder.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.components;
2 |
3 | import feign.QueryMapEncoder;
4 | import io.microsphere.logging.Logger;
5 | import org.springframework.cloud.context.named.NamedContextFactory;
6 | import org.springframework.cloud.openfeign.FeignClientProperties;
7 | import org.springframework.cloud.openfeign.FeignClientSpecification;
8 |
9 | import java.lang.invoke.MethodHandle;
10 | import java.util.Map;
11 |
12 | import static io.microsphere.invoke.MethodHandleUtils.findVirtual;
13 | import static io.microsphere.logging.LoggerFactory.getLogger;
14 |
15 | /**
16 | * @author 韩超
17 | * @since 0.0.1
18 | */
19 | public class DecoratedQueryMapEncoder extends DecoratedFeignComponent implements QueryMapEncoder {
20 |
21 | private static final Logger logger = getLogger(DecoratedQueryMapEncoder.class);
22 |
23 | private static final String getQueryMapEncoderMethodName = "getQueryMapEncoder";
24 |
25 | private static final MethodHandle getQueryMapEncoderMethodHandle = findVirtual(FeignClientProperties.FeignClientConfiguration.class, getQueryMapEncoderMethodName);
26 |
27 | public DecoratedQueryMapEncoder(String contextId, NamedContextFactory contextFactory, FeignClientProperties clientProperties, QueryMapEncoder delegate) {
28 | super(contextId, contextFactory, clientProperties, delegate);
29 | }
30 |
31 | @Override
32 | protected Class componentType() {
33 | Class queryMapEncoderClass = getQueryMapEncoder(getCurrentConfiguration());
34 | if (queryMapEncoderClass == null) {
35 | queryMapEncoderClass = getQueryMapEncoder(getDefaultConfiguration());
36 | }
37 | return queryMapEncoderClass == null ? QueryMapEncoder.class : queryMapEncoderClass;
38 | }
39 |
40 | private Class getQueryMapEncoder(FeignClientProperties.FeignClientConfiguration feignClientConfiguration) {
41 | if (feignClientConfiguration == null || getQueryMapEncoderMethodHandle == null) {
42 | return null;
43 | }
44 | Class queryMapEncoderClass = null;
45 | try {
46 | queryMapEncoderClass = (Class) getQueryMapEncoderMethodHandle.invokeExact(feignClientConfiguration);
47 | } catch (Throwable e) {
48 | if (logger.isWarnEnabled()) {
49 | logger.warn("FeignClientProperties.FeignClientConfiguration#getQueryMapEncoder() method can't be invoked , instance : {}", feignClientConfiguration);
50 | }
51 | }
52 | return queryMapEncoderClass;
53 | }
54 |
55 | @Override
56 | public Map encode(Object object) {
57 | return delegate().encode(object);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/components/DecoratedRetryer.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.components;
2 |
3 | import feign.RetryableException;
4 | import feign.Retryer;
5 | import org.springframework.cloud.context.named.NamedContextFactory;
6 | import org.springframework.cloud.openfeign.FeignClientProperties;
7 | import org.springframework.cloud.openfeign.FeignClientSpecification;
8 |
9 | /**
10 | * @author 韩超
11 | * @since 0.0.1
12 | */
13 | public class DecoratedRetryer extends DecoratedFeignComponent implements Retryer {
14 |
15 | public DecoratedRetryer(String contextId, NamedContextFactory contextFactory, FeignClientProperties clientProperties, Retryer delegate) {
16 | super(contextId, contextFactory, clientProperties, delegate);
17 | }
18 |
19 | @Override
20 | protected Class componentType() {
21 | Class retryerClass = null;
22 | if (getDefaultConfiguration() != null && getDefaultConfiguration().getRetryer() != null)
23 | retryerClass = getDefaultConfiguration().getRetryer();
24 |
25 | if (getCurrentConfiguration() != null && getCurrentConfiguration().getRetryer() != null)
26 | retryerClass = getCurrentConfiguration().getRetryer();
27 |
28 | if (retryerClass != null)
29 | return retryerClass;
30 | return Retryer.class;
31 | }
32 |
33 | @Override
34 | public void continueOrPropagate(RetryableException e) {
35 | Retryer retryer = delegate();
36 | if (retryer != null)
37 | retryer.continueOrPropagate(e);
38 | }
39 |
40 | @Override
41 | public Retryer clone() {
42 | return delegate().clone();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/components/NoOpRequestInterceptor.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.components;
2 |
3 | import feign.RequestInterceptor;
4 | import feign.RequestTemplate;
5 |
6 | /**
7 | * @author 韩超
8 | * @since 0.0.1
9 | */
10 | public class NoOpRequestInterceptor implements RequestInterceptor {
11 |
12 | public static final NoOpRequestInterceptor INSTANCE = new NoOpRequestInterceptor();
13 |
14 | private NoOpRequestInterceptor() {};
15 |
16 | @Override
17 | public void apply(RequestTemplate template) {
18 | //no op
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/components/Refreshable.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.components;
2 |
3 | /**
4 | * @author 韩超
5 | * @since 0.0.1
6 | */
7 | @FunctionalInterface
8 | public interface Refreshable {
9 | void refresh();
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports:
--------------------------------------------------------------------------------
1 | io.microsphere.spring.cloud.openfeign.autoconfigure.FeignClientAutoRefreshAutoConfiguration
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/BaseClient.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign;
2 |
3 | import org.springframework.cloud.openfeign.FeignClient;
4 | import org.springframework.web.bind.annotation.GetMapping;
5 | import org.springframework.web.bind.annotation.RequestBody;
6 | import org.springframework.web.bind.annotation.RequestParam;
7 |
8 | /**
9 | * @author 韩超
10 | * @since 0.0.1
11 | */
12 | @FeignClient(contextId = "my-client", name = "my-client", configuration = {MockCapability.class})
13 | public interface BaseClient {
14 |
15 | @GetMapping("echo")
16 | public String echo(@RequestBody String value, @RequestParam("version") String version);
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/BaseTest.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign;
2 |
3 | import io.microsphere.spring.cloud.openfeign.autoconfigure.EnableFeignAutoRefresh;
4 | import org.junit.jupiter.api.Test;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
9 | import org.springframework.cloud.endpoint.event.RefreshEvent;
10 | import org.springframework.cloud.openfeign.EnableFeignClients;
11 | import org.springframework.context.ApplicationEventPublisher;
12 | import org.springframework.context.annotation.ComponentScan;
13 | import org.springframework.core.env.ConfigurableEnvironment;
14 | import org.springframework.core.env.Environment;
15 | import org.springframework.core.env.MapPropertySource;
16 | import org.springframework.core.env.MutablePropertySources;
17 | import org.springframework.test.context.TestPropertySource;
18 |
19 | import java.util.Collections;
20 | import java.util.HashMap;
21 | import java.util.Map;
22 | import java.util.Set;
23 |
24 | /**
25 | * @author 韩超
26 | * @since 0.0.1
27 | */
28 | @TestPropertySource(properties = {
29 | "spring.main.allow-bean-definition-overriding=true",
30 | "spring.cloud.openfeign.client.config.default.encoder=io.microsphere.spring.cloud.openfeign.encoder.AEncoder",
31 | "spring.cloud.openfeign.client.config.default.error-decoder=io.microsphere.spring.cloud.openfeign.errordecoder.AErrorDecoder",
32 | "spring.cloud.openfeign.client.config.default.query-map-encoder=io.microsphere.spring.cloud.openfeign.querymapencoder.AQueryMapEncoder",
33 | "spring.cloud.openfeign.client.config.default.retryer=io.microsphere.spring.cloud.openfeign.retryer.ARetry",
34 | "spring.cloud.openfeign.client.config.default.decoder=io.microsphere.spring.cloud.openfeign.decoder.ADecoder",
35 | "spring.cloud.openfeign.client.config.default.request-interceptors[0]=io.microsphere.spring.cloud.openfeign.requestInterceptor.ARequestInterceptor",
36 | "spring.cloud.openfeign.client.config.default.default-request-headers.app=my-app",
37 | "spring.cloud.openfeign.client.config.default.default-query-parameters.sign=my-sign",
38 | })
39 | @ComponentScan(basePackages = "io.microsphere.spring.cloud.openfeign")
40 | @EnableFeignClients(clients = BaseClient.class)
41 | @EnableFeignAutoRefresh
42 | public abstract class BaseTest {
43 |
44 | private static final Logger log = LoggerFactory.getLogger(BaseTest.class);
45 | @Autowired
46 | private ApplicationEventPublisher publisher;
47 | @Autowired
48 | private Environment environment;
49 | @Autowired
50 | private BaseClient client;
51 |
52 | protected abstract String afterTestComponentConfigKey();
53 | protected abstract Class extends T> beforeTestComponentClass();
54 | protected abstract Class extends T> afterTestComponent();
55 | protected abstract FeignComponentAssert loadFeignComponentAssert();
56 |
57 | public void replaceConfig() {
58 | final String key = afterTestComponentConfigKey();
59 | Set keys = Collections.singleton(key);
60 | final Class> className = afterTestComponent();
61 | MutablePropertySources propertySources = ((ConfigurableEnvironment)this.environment).getPropertySources();
62 | Map map = new HashMap<>();
63 | log.trace("replacing config key {} with value {}", key, className.getName());
64 | map.put(key, className);
65 | propertySources.addFirst(new MapPropertySource("after", map));
66 |
67 | EnvironmentChangeEvent event = new EnvironmentChangeEvent(keys);
68 |
69 | triggerRefreshEvent();
70 |
71 | this.publisher.publishEvent(event);
72 | }
73 |
74 | @Test
75 | public void testInternal() {
76 | ObservableFeignInvocationHandler.componentAssert = loadFeignComponentAssert();
77 |
78 | ObservableFeignInvocationHandler.expectComponentClass = beforeTestComponentClass();
79 | try {
80 | this.client.echo("hello", "1.0");
81 | } catch (Exception ignored) {
82 | }
83 | replaceConfig();
84 |
85 | ObservableFeignInvocationHandler.expectComponentClass = afterTestComponent();
86 | try {
87 | this.client.echo("world", "1.0");
88 | } catch (Exception ignored) {
89 |
90 | }
91 | }
92 |
93 | protected void triggerRefreshEvent() {
94 | this.publisher.publishEvent(new RefreshEvent(new Object(), new Object(), "test"));
95 | }
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/FeignComponentAssert.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign;
2 |
3 | import feign.ResponseHandler;
4 |
5 | /**
6 | * @author 韩超
7 | * @since 0.0.1
8 | */
9 | public abstract class FeignComponentAssert {
10 |
11 |
12 | protected abstract T loadCurrentComponent(Object configuration, ResponseHandler responseHandler) throws Exception;
13 |
14 | public boolean expect(Object configuration, ResponseHandler responseHandler, Class expectedClass) throws Exception {
15 | T component = loadCurrentComponent(configuration, responseHandler);
16 | return expectedClass.equals(component.getClass());
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/MockCapability.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign;
2 |
3 | import feign.Capability;
4 | import feign.InvocationHandlerFactory;
5 |
6 | /**
7 | * @author 韩超
8 | * @since 0.0.1
9 | */
10 | public class MockCapability implements Capability {
11 |
12 | @Override
13 | public InvocationHandlerFactory enrich(InvocationHandlerFactory invocationHandlerFactory) {
14 | return ObservableFeignInvocationHandler::new;
15 | }
16 |
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/ObservableFeignInvocationHandler.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign;
2 |
3 | import feign.InvocationHandlerFactory;
4 | import feign.ResponseHandler;
5 | import feign.Target;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.util.Assert;
9 | import org.springframework.util.ClassUtils;
10 |
11 | import java.lang.reflect.Field;
12 | import java.lang.reflect.InvocationHandler;
13 | import java.lang.reflect.Method;
14 | import java.lang.reflect.Proxy;
15 | import java.util.Map;
16 |
17 | import static feign.Util.checkNotNull;
18 |
19 | /**
20 | * @author 韩超
21 | * @since 0.0.1
22 | */
23 | public class ObservableFeignInvocationHandler implements InvocationHandler {
24 |
25 |
26 | private static final Logger log = LoggerFactory.getLogger(ObservableFeignInvocationHandler.class);
27 | public static FeignComponentAssert> componentAssert;
28 | public static Class expectComponentClass;
29 |
30 | private final Target target;
31 | private final Map dispatch;
32 |
33 | ObservableFeignInvocationHandler(Target target, Map dispatch) {
34 | this.target = checkNotNull(target, "target");
35 | this.dispatch = checkNotNull(dispatch, "dispatch for %s", target);
36 | }
37 |
38 | @Override
39 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
40 | if ("equals".equals(method.getName())) {
41 | try {
42 | Object otherHandler =
43 | args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
44 | return equals(otherHandler);
45 | } catch (IllegalArgumentException e) {
46 | return false;
47 | }
48 | } else if ("hashCode".equals(method.getName())) {
49 | return hashCode();
50 | } else if ("toString".equals(method.getName())) {
51 | return toString();
52 | } else if (!dispatch.containsKey(method)) {
53 | throw new UnsupportedOperationException(
54 | String.format("Method \"%s\" should not be called", method.getName()));
55 | }
56 |
57 | InvocationHandlerFactory.MethodHandler methodHandler = dispatch.get(method);
58 | Object methodHandlerConfiguration = loadMethodHandlerConfiguration(methodHandler);
59 | ResponseHandler responseHandler = loadResponseHandler(methodHandler);
60 | Assert.isTrue(componentAssert.expect(methodHandlerConfiguration, responseHandler, expectComponentClass), "unexpected component");
61 | log.info("component validation is True");
62 | return dispatch.get(method).invoke(args);
63 | }
64 |
65 | protected Object loadMethodHandlerConfiguration(InvocationHandlerFactory.MethodHandler methodHandler) throws Exception {
66 | if (ClassUtils.isPresent("feign.MethodHandlerConfiguration", ObservableFeignInvocationHandler.class.getClassLoader())) {
67 | Class> configurationType = methodHandler.getClass();
68 | Field field = configurationType.getDeclaredField("methodHandlerConfiguration");
69 | field.setAccessible(true);
70 | return field.get(methodHandler);
71 | }
72 | return methodHandler;
73 |
74 | }
75 |
76 | protected ResponseHandler loadResponseHandler(InvocationHandlerFactory.MethodHandler methodHandler) throws Exception {
77 | Class> configurationType = methodHandler.getClass();
78 | Field field = configurationType.getDeclaredField("responseHandler");
79 | field.setAccessible(true);
80 | return (ResponseHandler) field.get(methodHandler);
81 | }
82 |
83 | @Override
84 | public boolean equals(Object obj) {
85 | if (obj instanceof ObservableFeignInvocationHandler) {
86 | ObservableFeignInvocationHandler other = (ObservableFeignInvocationHandler) obj;
87 | return target.equals(other.target);
88 | }
89 | return false;
90 | }
91 |
92 | @Override
93 | public int hashCode() {
94 | return target.hashCode();
95 | }
96 |
97 | @Override
98 | public String toString() {
99 | return target.toString();
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/decoder/ADecoder.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.decoder;
2 |
3 | import feign.FeignException;
4 | import feign.Response;
5 | import feign.codec.DecodeException;
6 | import feign.codec.Decoder;
7 |
8 | import java.io.IOException;
9 | import java.lang.reflect.Type;
10 |
11 | /**
12 | * @author 韩超
13 | * @since 0.0.1
14 | */
15 | public class ADecoder implements Decoder {
16 |
17 | @Override
18 | public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {
19 | return null;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/decoder/BDecoder.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.decoder;
2 |
3 | import feign.FeignException;
4 | import feign.Response;
5 | import feign.codec.DecodeException;
6 | import feign.codec.Decoder;
7 |
8 | import java.io.IOException;
9 | import java.lang.reflect.Type;
10 |
11 | /**
12 | * @author 韩超
13 | * @since 0.0.1
14 | */
15 | public class BDecoder implements Decoder {
16 |
17 | @Override
18 | public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {
19 | return null;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/decoder/DecoderChangedTest.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.decoder;
2 |
3 | import feign.codec.Decoder;
4 | import io.microsphere.spring.cloud.openfeign.BaseTest;
5 | import io.microsphere.spring.cloud.openfeign.FeignComponentAssert;
6 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 |
9 | /**
10 | * @author 韩超
11 | * @since 0.0.1
12 | */
13 | @SpringBootTest(classes = DecoderChangedTest.class)
14 | @EnableAutoConfiguration
15 | public class DecoderChangedTest extends BaseTest {
16 |
17 | @Override
18 | protected String afterTestComponentConfigKey() {
19 | return "spring.cloud.openfeign.client.config.my-client.decoder";
20 | }
21 |
22 | @Override
23 | protected Class extends Decoder> beforeTestComponentClass() {
24 | return ADecoder.class;
25 | }
26 |
27 | @Override
28 | protected Class extends Decoder> afterTestComponent() {
29 | return BDecoder.class;
30 | }
31 |
32 | @Override
33 | protected FeignComponentAssert loadFeignComponentAssert() {
34 | return new DecoderComponentAssert();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/decoder/DecoderComponentAssert.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.decoder;
2 |
3 | import feign.ResponseHandler;
4 | import feign.codec.Decoder;
5 | import io.microsphere.spring.cloud.openfeign.FeignComponentAssert;
6 | import io.microsphere.spring.cloud.openfeign.components.DecoratedDecoder;
7 |
8 | import java.lang.reflect.Field;
9 |
10 | /**
11 | * @author 韩超
12 | * @since 0.0.1
13 | */
14 | public class DecoderComponentAssert extends FeignComponentAssert {
15 |
16 | @Override
17 | protected Decoder loadCurrentComponent(Object configuration, ResponseHandler responseHandler) throws Exception {
18 | Class responseHandlerClass = ResponseHandler.class;
19 | Field decoderField = responseHandlerClass.getDeclaredField("decoder");
20 | decoderField.setAccessible(true);
21 | DecoratedDecoder decoder = (DecoratedDecoder)decoderField.get(responseHandler);
22 | return decoder.delegate();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/encoder/AEncoder.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.encoder;
2 |
3 | import feign.RequestTemplate;
4 | import feign.codec.EncodeException;
5 | import feign.codec.Encoder;
6 |
7 | import java.lang.reflect.Type;
8 |
9 | /**
10 | * @author 韩超
11 | * @since 0.0.1
12 | */
13 | public class AEncoder implements Encoder {
14 |
15 | @Override
16 | public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {
17 | template.body(object.toString());
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/encoder/BEncoder.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.encoder;
2 |
3 | import feign.RequestTemplate;
4 | import feign.codec.EncodeException;
5 | import feign.codec.Encoder;
6 |
7 | import java.lang.reflect.Type;
8 |
9 | /**
10 | * @author 韩超
11 | * @since 0.0.1
12 | */
13 | public class BEncoder implements Encoder {
14 |
15 | @Override
16 | public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {
17 | template.body(object.toString());
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/encoder/EncoderChangedTest.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.encoder;
2 |
3 | import feign.codec.Encoder;
4 | import io.microsphere.spring.cloud.openfeign.BaseTest;
5 | import io.microsphere.spring.cloud.openfeign.FeignComponentAssert;
6 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 |
9 | /**
10 | * @author 韩超
11 | * @since 0.0.1
12 | */
13 | @SpringBootTest(classes = EncoderChangedTest.class)
14 | @EnableAutoConfiguration
15 | public class EncoderChangedTest extends BaseTest {
16 |
17 |
18 | @Override
19 | protected Class extends Encoder> beforeTestComponentClass() {
20 | return AEncoder.class;
21 | }
22 |
23 | @Override
24 | protected FeignComponentAssert loadFeignComponentAssert() {
25 | return EncoderComponentAssert.INSTANCE;
26 | }
27 |
28 | @Override
29 | protected String afterTestComponentConfigKey() {
30 | return "spring.cloud.openfeign.client.config.my-client.encoder";
31 | }
32 |
33 | @Override
34 | protected Class extends Encoder> afterTestComponent() {
35 | return BEncoder.class;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/encoder/EncoderComponentAssert.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.encoder;
2 |
3 | import feign.ResponseHandler;
4 | import feign.codec.Encoder;
5 | import io.microsphere.spring.cloud.openfeign.FeignComponentAssert;
6 | import io.microsphere.spring.cloud.openfeign.components.DecoratedEncoder;
7 |
8 | import java.lang.reflect.Field;
9 |
10 | /**
11 | * @author 韩超
12 | * @since 0.0.1
13 | */
14 | public class EncoderComponentAssert extends FeignComponentAssert {
15 |
16 | public static final EncoderComponentAssert INSTANCE = new EncoderComponentAssert();
17 |
18 | private EncoderComponentAssert() {
19 |
20 | }
21 |
22 | @Override
23 | protected Encoder loadCurrentComponent(Object configuration, ResponseHandler responseHandler) throws Exception {
24 | Class> configurationClass = configuration.getClass();
25 | Field buildTemplateFromArgs = configurationClass.getDeclaredField("buildTemplateFromArgs");
26 | buildTemplateFromArgs.setAccessible(true);
27 | Object buildTemplateFromArgsValue = buildTemplateFromArgs.get(configuration);
28 | Class> buildTemplateFromArgsType = buildTemplateFromArgsValue.getClass();
29 | Field encoderField = buildTemplateFromArgsType.getDeclaredField("encoder");
30 | encoderField.setAccessible(true);
31 | DecoratedEncoder encoder = (DecoratedEncoder)encoderField.get(buildTemplateFromArgsValue);
32 | return encoder.delegate();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/errordecoder/AErrorDecoder.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.errordecoder;
2 |
3 | import feign.Response;
4 | import feign.codec.ErrorDecoder;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | /**
9 | * @author 韩超
10 | * @since 1.0
11 | */
12 | public class AErrorDecoder implements ErrorDecoder {
13 |
14 | private static final Logger log = LoggerFactory.getLogger(AErrorDecoder.class);
15 |
16 | @Override
17 | public Exception decode(String methodKey, Response response) {
18 | return new IllegalArgumentException("");
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/errordecoder/BErrorEncoder.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.errordecoder;
2 |
3 | import feign.Response;
4 | import feign.codec.ErrorDecoder;
5 |
6 | /**
7 | * @author 韩超
8 | * @since 0.0.1
9 | */
10 | public class BErrorEncoder implements ErrorDecoder {
11 |
12 | @Override
13 | public Exception decode(String methodKey, Response response) {
14 | return null;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/errordecoder/ErrorDecoderChangedTest.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.errordecoder;
2 |
3 | import feign.codec.ErrorDecoder;
4 | import io.microsphere.spring.cloud.openfeign.BaseTest;
5 | import io.microsphere.spring.cloud.openfeign.FeignComponentAssert;
6 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 |
9 | /**
10 | * @author 韩超
11 | * @since 1.0
12 | */
13 | @SpringBootTest(classes = ErrorDecoderChangedTest.class)
14 | @EnableAutoConfiguration
15 | public class ErrorDecoderChangedTest extends BaseTest {
16 |
17 | @Override
18 | protected Class extends ErrorDecoder> beforeTestComponentClass() {
19 | return AErrorDecoder.class;
20 | }
21 |
22 | @Override
23 | protected FeignComponentAssert loadFeignComponentAssert() {
24 | return new ErrorDecoderComponentAssert();
25 | }
26 |
27 | @Override
28 | protected String afterTestComponentConfigKey() {
29 | return "spring.cloud.openfeign.client.config.my-client.error-decoder";
30 | }
31 |
32 | @Override
33 | protected Class extends ErrorDecoder> afterTestComponent() {
34 | return BErrorEncoder.class;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/errordecoder/ErrorDecoderComponentAssert.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.errordecoder;
2 |
3 | import feign.ResponseHandler;
4 | import feign.codec.ErrorDecoder;
5 | import io.microsphere.spring.cloud.openfeign.FeignComponentAssert;
6 | import io.microsphere.spring.cloud.openfeign.components.DecoratedErrorDecoder;
7 |
8 | import java.lang.reflect.Field;
9 |
10 | /**
11 | * @author 韩超
12 | * @since 0.0.1
13 | */
14 | public class ErrorDecoderComponentAssert extends FeignComponentAssert {
15 |
16 | @Override
17 | protected ErrorDecoder loadCurrentComponent(Object configuration, ResponseHandler responseHandler) throws Exception {
18 | Class responseHandlerClass = ResponseHandler.class;
19 | Field errorDecoderField = responseHandlerClass.getDeclaredField("errorDecoder");
20 | errorDecoderField.setAccessible(true);
21 | DecoratedErrorDecoder errorDecoder = (DecoratedErrorDecoder)errorDecoderField.get(responseHandler);
22 | return errorDecoder.delegate();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/querymapencoder/AQueryMapEncoder.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.querymapencoder;
2 |
3 | import feign.QueryMapEncoder;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | import java.util.HashMap;
8 | import java.util.Map;
9 |
10 | /**
11 | * @author 韩超
12 | * @since 1.0
13 | */
14 | public class AQueryMapEncoder implements QueryMapEncoder {
15 |
16 |
17 | private static final Logger log = LoggerFactory.getLogger(AQueryMapEncoder.class);
18 |
19 | @Override
20 | public Map encode(Object object) {
21 | return new HashMap<>();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/querymapencoder/BQueryMapEncoder.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.querymapencoder;
2 |
3 | import feign.QueryMapEncoder;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | import java.util.HashMap;
8 | import java.util.Map;
9 |
10 | /**
11 | * @author 韩超
12 | * @since 1.0
13 | */
14 | public class BQueryMapEncoder implements QueryMapEncoder {
15 |
16 |
17 | private static final Logger log = LoggerFactory.getLogger(BQueryMapEncoder.class);
18 |
19 | @Override
20 | public Map encode(Object object) {
21 | return new HashMap<>();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/querymapencoder/QueryMapEncoderChangedTest.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.querymapencoder;
2 |
3 | import feign.QueryMapEncoder;
4 | import io.microsphere.spring.cloud.openfeign.BaseTest;
5 | import io.microsphere.spring.cloud.openfeign.FeignComponentAssert;
6 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 |
9 | /**
10 | * @author 韩超
11 | * @since 1.0
12 | */
13 | @SpringBootTest(classes = QueryMapEncoderChangedTest.class)
14 | @EnableAutoConfiguration
15 | public class QueryMapEncoderChangedTest extends BaseTest {
16 |
17 | @Override
18 | protected Class extends QueryMapEncoder> beforeTestComponentClass() {
19 | return AQueryMapEncoder.class;
20 | }
21 |
22 | @Override
23 | protected FeignComponentAssert loadFeignComponentAssert() {
24 | return new QueryMapEncoderComponentAssert();
25 | }
26 |
27 | @Override
28 | protected String afterTestComponentConfigKey() {
29 | return "spring.cloud.openfeign.client.config.my-client.query-map-encoder";
30 | }
31 |
32 | @Override
33 | protected Class extends QueryMapEncoder> afterTestComponent() {
34 | return BQueryMapEncoder.class;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/querymapencoder/QueryMapEncoderComponentAssert.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.querymapencoder;
2 |
3 | import feign.QueryMapEncoder;
4 | import feign.ResponseHandler;
5 | import io.microsphere.spring.cloud.openfeign.FeignComponentAssert;
6 | import io.microsphere.spring.cloud.openfeign.components.DecoratedQueryMapEncoder;
7 |
8 | import java.lang.reflect.Field;
9 |
10 | /**
11 | * @author 韩超
12 | * @since 0.0.1
13 | */
14 | public class QueryMapEncoderComponentAssert extends FeignComponentAssert {
15 |
16 | @Override
17 | protected QueryMapEncoder loadCurrentComponent(Object configuration, ResponseHandler responseHandler) throws Exception {
18 | Class> configurationClass = configuration.getClass();
19 | Field buildTemplateFromArgs = configurationClass.getDeclaredField("buildTemplateFromArgs");
20 | buildTemplateFromArgs.setAccessible(true);
21 | Object buildTemplateFromArgsValue = buildTemplateFromArgs.get(configuration);
22 | Class> buildTemplateFromArgsType = buildTemplateFromArgsValue.getClass().getSuperclass();
23 | Field encoderField = buildTemplateFromArgsType.getDeclaredField("queryMapEncoder");
24 | encoderField.setAccessible(true);
25 | DecoratedQueryMapEncoder encoder = (DecoratedQueryMapEncoder)encoderField.get(buildTemplateFromArgsValue);
26 | return encoder.delegate();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/requestInterceptor/ARequestInterceptor.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.requestInterceptor;
2 |
3 | import feign.RequestInterceptor;
4 | import feign.RequestTemplate;
5 |
6 | /**
7 | * @author 韩超
8 | * @since 0.0.1
9 | */
10 | public class ARequestInterceptor implements RequestInterceptor {
11 |
12 | @Override
13 | public void apply(RequestTemplate template) {
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/requestInterceptor/BRequestInterceptor.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.requestInterceptor;
2 |
3 | import feign.RequestInterceptor;
4 | import feign.RequestTemplate;
5 |
6 | /**
7 | * @author 韩超
8 | * @since 0.0.1
9 | */
10 | public class BRequestInterceptor implements RequestInterceptor {
11 |
12 | @Override
13 | public void apply(RequestTemplate template) {
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/requestInterceptor/RequestInterceptorChangedTest.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.requestInterceptor;
2 |
3 | import feign.RequestInterceptor;
4 | import io.microsphere.spring.cloud.openfeign.BaseTest;
5 | import io.microsphere.spring.cloud.openfeign.FeignComponentAssert;
6 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 |
9 | /**
10 | * @author 韩超
11 | * @since 0.0.1
12 | */
13 | @SpringBootTest(classes = RequestInterceptorChangedTest.class, webEnvironment = SpringBootTest.WebEnvironment.NONE)
14 | @EnableAutoConfiguration
15 | public class RequestInterceptorChangedTest extends BaseTest {
16 |
17 | @Override
18 | protected Class extends RequestInterceptor> beforeTestComponentClass() {
19 | return ARequestInterceptor.class;
20 | }
21 |
22 | @Override
23 | protected FeignComponentAssert loadFeignComponentAssert() {
24 | return new RequestInterceptorComponentAssert();
25 | }
26 |
27 | @Override
28 | protected String afterTestComponentConfigKey() {
29 | return "spring.cloud.openfeign.client.config.my-client.request-interceptors[0]";
30 | }
31 |
32 | @Override
33 | protected Class extends RequestInterceptor> afterTestComponent() {
34 | return BRequestInterceptor.class;
35 | }
36 |
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/requestInterceptor/RequestInterceptorComponentAssert.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.requestInterceptor;
2 |
3 | import feign.RequestInterceptor;
4 | import feign.ResponseHandler;
5 | import io.microsphere.spring.cloud.openfeign.FeignComponentAssert;
6 | import io.microsphere.spring.cloud.openfeign.components.CompositedRequestInterceptor;
7 |
8 | import java.lang.reflect.Field;
9 | import java.util.List;
10 |
11 | /**
12 | * @author 韩超
13 | * @since 0.0.1
14 | */
15 | public class RequestInterceptorComponentAssert extends FeignComponentAssert {
16 |
17 | @Override
18 | protected CompositedRequestInterceptor loadCurrentComponent(Object configuration, ResponseHandler responseHandler) throws Exception {
19 | Class> configurationClass = configuration.getClass();
20 | Field retryField = configurationClass.getDeclaredField("requestInterceptors");
21 | retryField.setAccessible(true);
22 | List retryer = (List) retryField.get(configuration);
23 | for (RequestInterceptor interceptor : retryer) {
24 | if (interceptor instanceof CompositedRequestInterceptor) {
25 | return (CompositedRequestInterceptor) interceptor;
26 | }
27 | }
28 | return null;
29 | }
30 |
31 | @Override
32 | public boolean expect(Object configuration, ResponseHandler responseHandler, Class expectedClass) throws Exception {
33 | CompositedRequestInterceptor requestInterceptor = loadCurrentComponent(configuration, responseHandler);
34 | for(RequestInterceptor interceptor : requestInterceptor.getRequestInterceptors()) {
35 | if (expectedClass.equals(interceptor.getClass()))
36 | return true;
37 | }
38 | return false;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/retryer/ARetry.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.retryer;
2 |
3 | import feign.RetryableException;
4 | import feign.Retryer;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | /**
9 | * @author 韩超
10 | * @since 1.0
11 | */
12 | public class ARetry implements Retryer {
13 |
14 | private static final Logger log = LoggerFactory.getLogger(ARetry.class);
15 |
16 | @Override
17 | public void continueOrPropagate(RetryableException e) {
18 | log.trace("Attempting to propagate exception", e);
19 | }
20 |
21 | @Override
22 | public Retryer clone() {
23 | return this;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/retryer/BRetry.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.retryer;
2 |
3 | import feign.RetryableException;
4 | import feign.Retryer;
5 |
6 | /**
7 | * @author 韩超
8 | * @since 0.0.1
9 | */
10 | public class BRetry implements Retryer {
11 |
12 | @Override
13 | public void continueOrPropagate(RetryableException e) {
14 |
15 | }
16 |
17 | @Override
18 | public Retryer clone() {
19 | return this;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/retryer/RetryerChangedTest.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.retryer;
2 |
3 | import feign.Retryer;
4 | import io.microsphere.spring.cloud.openfeign.BaseTest;
5 | import io.microsphere.spring.cloud.openfeign.FeignComponentAssert;
6 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 |
9 | /**
10 | * @author 韩超
11 | * @since 1.0
12 | */
13 | @SpringBootTest(classes = RetryerChangedTest.class)
14 | @EnableAutoConfiguration
15 | public class RetryerChangedTest extends BaseTest {
16 |
17 | @Override
18 | protected Class extends Retryer> beforeTestComponentClass() {
19 | return ARetry.class;
20 | }
21 |
22 | @Override
23 | protected FeignComponentAssert loadFeignComponentAssert() {
24 | return new RetryerComponentAssert();
25 | }
26 |
27 | @Override
28 | protected String afterTestComponentConfigKey() {
29 | return "spring.cloud.openfeign.client.config.my-client.retryer";
30 | }
31 |
32 | @Override
33 | protected Class extends Retryer> afterTestComponent() {
34 | return BRetry.class;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/microsphere-spring-cloud-openfeign/src/test/java/io/microsphere/spring/cloud/openfeign/retryer/RetryerComponentAssert.java:
--------------------------------------------------------------------------------
1 | package io.microsphere.spring.cloud.openfeign.retryer;
2 |
3 | import feign.ResponseHandler;
4 | import feign.Retryer;
5 | import io.microsphere.spring.cloud.openfeign.FeignComponentAssert;
6 | import io.microsphere.spring.cloud.openfeign.components.DecoratedRetryer;
7 |
8 | import java.lang.reflect.Field;
9 |
10 | /**
11 | * @author 韩超
12 | * @since 0.0.1
13 | */
14 | public class RetryerComponentAssert extends FeignComponentAssert {
15 |
16 | @Override
17 | protected Retryer loadCurrentComponent(Object configuration, ResponseHandler responseHandler) throws Exception {
18 | Class> configurationClass = configuration.getClass();
19 | Field retryField = configurationClass.getDeclaredField("retryer");
20 | retryField.setAccessible(true);
21 | DecoratedRetryer retryer = (DecoratedRetryer) retryField.get(configuration);
22 | return retryer.delegate();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | io.github.microsphere-projects
7 | microsphere-build
8 | 0.1.1
9 |
10 | 4.0.0
11 |
12 | io.github.microsphere-projects
13 | microsphere-spring-cloud
14 | ${revision}
15 | pom
16 |
17 | Microsphere :: Spring Cloud
18 | Microsphere Spring Cloud
19 | https://github.com/microsphere-projects/microsphere-spring-cloud
20 |
21 |
22 | Microsphere
23 | https://github.com/microsphere-projects
24 |
25 |
26 |
27 |
28 | Apache License, Version 2.0
29 | http://www.apache.org/licenses/LICENSE-2.0
30 | repo
31 |
32 |
33 |
34 |
35 |
36 | mercyblitz
37 | Mercy Ma
38 | mercyblitz@gmail.com
39 | Microsphere
40 |
41 | lead
42 | architect
43 | developer
44 |
45 |
46 |
47 |
48 |
49 | git@github.com/microsphere-projects/microsphere-spring-cloud.git
50 | scm:git:${project.scm.url}
51 | scm:git:ssh://${project.scm.url}
52 |
53 |
54 |
55 | 2.0.0-SNAPSHOT
56 | 17
57 |
58 |
59 |
60 | microsphere-spring-cloud-parent
61 | microsphere-spring-cloud-dependencies
62 | microsphere-spring-cloud-commons
63 | microsphere-spring-cloud-openfeign
64 |
65 |
66 |
67 |
68 | ossrh
69 | https://s01.oss.sonatype.org/content/repositories/snapshots
70 |
71 |
72 | ossrh
73 | https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/
74 |
75 |
76 |
77 |
78 |
79 | snapshot
80 |
81 | true
82 |
83 |
84 | false
85 |
86 | https://s01.oss.sonatype.org/content/repositories/snapshots
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------